一道大水题,其实 O(n) 遍历就可以过,非常的简单。
class Solution {
public:
int findMin(vector<int>& nums) {
int ans = nums[0];
int len = nums.size();
for(int i=1;i<len;i++){
ans = min(ans, nums[i]);
}
}
};
但是对于这个题,还是有优化的办法的。当我看到 “ 有序 ” 、“ 求最小值 ” 这几个字眼的时候,就会想到能不能用二分查找。
由于这个题中的有序数列只被旋转了一次,也就是只在一个点处会出现递减,我们暂且称之为断点,这个断点就是我们要找的值,在断点左边的数肯定大于断点右边的数。那么对于 left 、 mid 、right ,若出现: n u m s [ l e f t ] > n u m s [ m i d ] nums[left] > nums[mid] nums[left]>nums[mid] 则说明左区间全部在断点的左侧,否则说明右区间全部在断点的右侧,这样就可以进行二分了,最后 nums[left] 和 nums[right] 中较小的那一个就是断点。
除此之外,还有一个重要的点要注意:
那就是不能让 left 、right 同时出现在断点的左侧或右侧。即当 mid 正好是断点或者断点左侧的点(即最大值点)时,需要进行特判。
class Solution{
public:
int findMin(vector<int>& nums)
{
int L = 0;
int R = nums.size() - 1;
while (R > L + 1){
int mid = (L + R) >> 1;
if (nums[L] < nums[mid])
{
if (nums[L] < nums[R])
{
return nums[L];
}
L = mid + 1;
}
else
{
if (nums[mid] < nums[mid - 1])
{
return nums[mid];
}
R = mid - 1;
}
}
return min(nums[L], nums[R]);
}
};
介绍了一种在旋转有序数组中寻找最小元素的高效算法。利用二分查找优化搜索过程,通过判断中间元素与首尾元素的关系来缩小搜索范围。
346

被折叠的 条评论
为什么被折叠?



