题目描述:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
解题代码:
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
//排除不可能
if(rotateArray.empty()){
return 0;
}
int leftIndex = 0;
int rightIndex = rotateArray.size() - 1;
int midIndex = leftIndex;
while(rotateArray[leftIndex] >= rotateArray[rightIndex]){
midIndex = (leftIndex + rightIndex) / 2;
//如果左右指针挨在一起了
if((rightIndex - leftIndex) == 1){
break;
}
//如果leftIndex, rightIndex, midIndex对应的数组值都是相同的则只能进入顺序查找
if((rotateArray[leftIndex] == rotateArray[rightIndex])
&&(rotateArray[leftIndex] == rotateArray[midIndex])){
return minOrder(rotateArray, leftIndex, rightIndex);
}
//二分法
if(rotateArray[midIndex] >= rotateArray[leftIndex]){
leftIndex = midIndex;
}else if(rotateArray[midIndex <= rotateArray[rightIndex]]){
rightIndex = midIndex;
}
}
return rotateArray[rightIndex];
}
private:
int minOrder(vector<int> rotateArray, int leftIndex, int rightIndex){
int result = rotateArray[leftIndex];
for(int i = leftIndex + 1; i <= rightIndex; i++){
if(result > rotateArray[i]){
result = rotateArray[i];
break;
}
}
return result;
}
};
解题思路:
- 简单的说,这道题就是找数组里最小的数
- 有很多种做法可以找数组里最小的数,比如遍历,但是如果用了遍历,那你就注定是拿不到欧肥儿的仔了。
- 遍历不如二分法查找优秀,二分法时间复杂度只有O(logn)。
- 由于题目给出线索,这个数组是其实是一个有序数组拆成的两个有序数组[小~大 小~大],所以这样二分法可以更简便得查找到最小的数。
- 但是单用二分法,如果遇到一个情况就GG了。那就是如果,左指针,右指针,中间指针指的数都相等的话,二分法是没有办法找到最小数的。比如[1, 0, 1, 1, 1]。所以如果遇到这种这种情况,我们只能把数组从左指针到右指针的这段数组截下来,顺序遍历得到最小数。