面试题11 :旋转数组的最小数字
题目描述:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3, 4, 5, 1, 2] 为 [1, 2, 3, 4, 5] 的一个旋转,该数组的最小值为 1 。
解法一:模拟二分查找
思路:
- 两个指针 left 和 right 指向数组两个边界
- 第三个指针 mid 指向数组中间的数
- 若 v[mid] >= v[left] ,更新 left 指针至 mid 处
- 若 v[mid] <= v[right] ,更新 right 指针至 mid 处
- 对于 [1 0 1 1 1] 这种特殊样例需要遍历数组进行寻找最小值
- 循环出口是当 right 和 left 相邻时,整个数组最小值是 right 指针指向的值
图解:
class Solution {
public:
int minNumberInRotateArray(vector<int> v) {
if(v.size() == 0) return 0;
int left = 0, right = v.size() - 1;
int mid = 0;
while(v[left] >= v[right])
{
if(right - left == 1) // 循环出口
{
mid = right;
break;
}
mid = (left + right) / 2;
if(v[mid] == v[left] && v[mid] == v[left]) // 处理特殊情况,例如:1 0 1 1 1
{
mid = order(v);
break;
}
if(v[mid] >= v[left]) // 移动左右指针
left = mid;
else if(v[mid] <= v[right])
right = mid;
}
return v[mid];
}
private:
int order(vector<int> v) // 遍历数组找出最小值的下标
{
int minIndex = 0;
for(int i = 0;i < v.size(); i++)
if(v[i] < v[minIndex]) minIndex = i;
return minIndex;
}
};