[剑指Offer笔记]08_查找与排序 minNumberInRotateArray
面试重点注意:
- 二叉查找
- 归并排序
- 快速排序
注意: 很多算法有递归和循环两种写法. 递归代码简洁,但性能不如循环的.
- 位运算! 是一种特殊的算法
与 或 异或 左移 右移
这五种操作
查找与排序
-
顺序查找 / 二分查找 / 哈希表查找 / 二叉排序树查找
-
对各类的排序算法都要烂熟于心,能够从额外空间消耗/平均时间复杂度和最差时间复杂度等方面
-
快排的重要思想:
现在数组中选择一个数字,然后把数组中的数组分成两个部分.
一个小于它,一个大于它.
题目描述:
-
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
分析:
-
在数字都不相同的情况下:
利用有两个递增的数组!
l指针始终指向 第一个数组!
r指针始终指向 第二个数组!
r-l==1时,则找到了最小值
实现:
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
int len = rotateArray.size();
if (len == 0)
return 0;
// 没有旋转
if (rotateArray[0] < rotateArray[len - 1])
return rotateArray[0];
else {
// 发生了旋转,则 [0] 一定> [len-1]
int l = 0, r = len - 1; // l指向第一个递增数组的最后一个数字,r指向第二个递增数组的第一个数字
while (l < r) {
if (r - l == 1) // 若相差1个,则找到了
break;
int mid = (r - l) / 2 + l;
if (rotateArray[mid] >= rotateArray[l]) {
// mid仍在第一个递增数组
l = mid;
}
else if (rotateArray[mid] <= rotateArray[r]) {
// mid仍在第二个递增数组
r = mid;
}
}
return rotateArray[r];
}
}
};
做题体会:
- 二分查找法! 最重要的是 定义好你的指针! 他们指向什么!从始到终一定要固定!!!