编程问题:
假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。请找出其中最小的元素。注意数组中可能存在重复的元素。
示例:
- 输入: [1,3,5]
输出: 1 - 输入: [2,2,2,0,1]
输出: 0
解法:
1.二分查找
最小值只会出现在非递增区间,因此和“搜索旋转排序数组”相反,需要寻找非递增的情况。如果没有发生旋转: 1 2 3 4 5 6, l对应的值一定小于r,如果发生旋转:5 6 | 1 2 3 4, 可以看到初始l定大于r。
class Solution {
public:
int findMin(vector<int>& nums) {
if (nums.size() == 0) return -1;
if (nums.size() == 1) return nums[0];
int l = 0, r = nums.size() - 1;
int mid;
while (l < r) //当l = r = mid的时候,nums[l] == nums[mid],此时按照代码会l++,跳过正确答案 因此让最外面的while循环是while(left < right),就避过了这个问题
{
mid = (l + r) / 2;
if (nums[l] < nums[r]) return nums[l];
if (nums[l] == nums[mid]) 相等的时候 l++ 跳过干扰项
l++;
else if (nums[l] < nums[mid]) 单调递增区间 最小值不会出现在这里
l = mid + 1;
else //无法排除mid
r = mid;
}
return nums[l];
}
};