旋转数组中的最小数字
1:采用二分法解答这个问题,
mid = low + (high - low)/2
需要考虑三种情况:
1.array[low]>array[high] : 用两个指针来操作: 相当于二分法 低位指针在第一个递增序列内;高位指针在第二个递增序列内;
(1)array[low]<array[mid] :
出现这种情况的array类似[3,4,5,6,0,1,2],此时最小数字一定在mid的右边。
low = mid + 1
(2)array[low]>array[mid] :
出现这种情况的array类似[5,1,2,3,4],此时最小数字一定就是array[mid]或者在mid的左
边。因为右边必然都是递增的。
high = mid
(3)循环的终止条件为: high-low==1; 因为到了两个指针相邻的地方,那么其实high 所对应的值即是最小值
2.array[low]<array[high] : //其实就是相当于将 一个本来的递增数列 后面0 个值旋转到前面去; 还是递增数列;第一个值为最小值
3 .array[low]==array[mid] == array[low]: //注意题目 这是个非递减 没说一定递增
出现这种情况的array类似 [1,0,1,1,1] 或者[1,1,1,0,1],此时最小数字不好判断在mid左边还是右边,这时只好一个一个试 ,
只能单独列出来 用顺序查找的方法来找到最小值;
class Solution { public: int minNumberInRotateArray(vector<int> rotateArray) { if(rotateArray.empty()) return 0; //第一种情况 全是递增 后面比前面大 两个指针操作 【12345】 //第二种情况 有可能相等的递增 【01111】 [11101] //第三种情况 递增数 只把后面0个转到前面来 int low=0; int high=rotateArray.size()-1; int mid=0; while(rotateArray.at(low)>=rotateArray.at(high)) { if (high-low==1) { return rotateArray.at(high); } mid=(low+high)/2; //第二种情况 三个都相等 if (rotateArray.at(low)==rotateArray.at(mid)&&rotateArray.at(low)==rotateArray.at(high)) return order(rotateArray);//去顺序查找 if(rotateArray.at(low)<=rotateArray.at(mid))//注意 有等于号 low=mid; else if(rotateArray.at(low)>=rotateArray.at(mid)) high=mid; } return rotateArray.at(low); } public: int order(vector<int> rotateArray) { int SIZE=rotateArray.size(); int min=rotateArray.at(0); for (int i=0;i<SIZE;i++) { if (rotateArray.at(i)<min) min=rotateArray.at(i); } return min; } };