剑指Offer——旋转数组的最小数字
题目:
这道题有三种思路:
- 以第一个元素为最小值
min
,直接遍历一遍,每个元素都与min
进行比较,当当前元素比最小值min
小则更新min
的值,这里的时间复杂度是O(n)
- 利用数组的特性,我们可以知道只要
a[i+1] < a[i]
那么就可以确定a[i+1]
就是最小值,这里的时间复杂度大概是O(1)~O(n)
之间,取决于最小值在哪 - 还是利用数组的特性:我们可以肯定,最左边的元素一定比最右边的元素大,这时候只需要取数组正中间的元素来进行比较,就可以确定中间的元素处于较大元素组成的区域(我们这里称之为左区)还是较小元素组成的区域(右区),确定的方法很简单,如果中间的元素比左边的大,那么可以确定在左区,就需要往右边搜索,如果比左边的元素小,那么定然是在右区,就要往左边找。时间复杂度在
O(1)~O(n/2)
之间
1、2很简单,所以这里就不放出代码了,我们只看3:
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
int size = rotateArray.size();
if(size == 0) {
return 0;
}
int left = rotateArray[0];
int right = rotateArray[size - 1];
int idx = size / 2;
int res = 0;
while(idx > 0 && idx < size) {
if(rotateArray[idx] > left && rotateArray[idx] <= rotateArray[idx + 1]) {
// 左区
++idx;
}
else if(rotateArray[idx] < right && rotateArray[idx] >= rotateArray[idx - 1]) {
// 右区
--idx;
}
else {
// 此时我们在边界,但是不确定idx此时在左区最右边还是右区最左边
res = rotateArray[idx] > rotateArray[idx + 1] ? rotateArray[idx + 1] : rotateArray[idx];
break;
}
}
return res;
}
};
本博客文章默认使用CC BY-SA 3.0协议。