难度:简单
题目描述:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
注:考察二分查找,二分查找时数组是有序的
思路: 利用旋转数字的特性,旋转数组可以看成两个排序的数组。采用两个指针分别指向数组的第一个元素和最后一个元素。第一个指针总是指向前面递增数组的元素,而第二个指针总是指着后面递增数组的元素。
寻找中间元素,如果中间元素位于前面的递增数组,那么他应该大于或等于第一个指针指向的元素,那么最小元素应该在后面的递增数组,这样把第一个指针指向中间位置,缩小查找范围,移动之后第一个指针仍然在前面的递增数组中;如果中间元素位于后面的递增数组,那么他应该小于或等于第二个指针指向的元素,那么最小元素应该在前面的递增数组,这样把第二个指针指向中间位置,缩小查找范围,移动之后第二个指针仍然在前面的递增数组中;
最终第一个指针指向前面数组的最后一个元素,而第二个指针就会指向后面数组的第一个元素,此时刚好也是最小的元素。就是说两指针会指向两相邻的元素,这是循环条件的结束。(源于剑指offer)
class Solution { public: int minNumberInRotateArray(vector<int> rotateArray) { if(rotateArray.size()==0) return 0; int left=0; int right=rotateArray.size()-1; int middle=-1; while(rotateArray[left]>=rotateArray[right]){ if(right-left==1){ middle=right; break; } middle=left+(right-left)/2; if(rotateArray[middle]>=rotateArray[left]) left=middle; if(rotateArray[middle]<=rotateArray[right]) right=middle; } return rotateArray[middle]; } };