Leetcode——153. 寻找旋转排序数组中的最小值

概述

题目链接

  • 局部有序数组内查找最小元素,数组内值互不相同

分析

  • 要求 O ( l o g n ) O(logn) O(logn),说明还是需要二分法,并且局部有序也是支持二分操作的

思路

Leetcode——153. 寻找旋转排序数组中的最小值_第1张图片

  • Q1:如何确定下一个查找区间?

    我们每次得到的值是num[mid],我们想要查找的值是min。由左图可知,当mid在1处时,应该查找右区间;当mid在2处时,应该查找左边区间

  • Q2:如何确定mid的位置?

    通过分析,num[mid]可以和num[l]num[r]比较

    • 如果和num[l]比较,num[mid]>时选择右区间;<时选择左区间
    • 如果和num[r]比较,num[mid]>时选择右区间;<时选择左区间
    • 但是注意特殊情况,也就是右图,我们知道num[mid]时,左区间;num[mid]>num[l]时选择左区间

    所以为了一致性,选择和num[r]相比

  • Q3:什么时候找到答案?

    因为我们的区间总是根据min值移动,所以当不用再移动区间时,就说明找到了min

    即,l==r时

实现代码

class Solution {
public:
    int findMin(vector<int>& nums) {
        int l = 0, r = nums.size() - 1;
        while ( l < r) {
            int mid = (l + r) / 2;
            if (nums[mid] < nums[r])	// 这里注意选择和num[r]比较而不是num[0]
                r = mid;				// 最小值有可能就是nums[mid]
            else
                l = mid + 1;
        }
        // 当 l == r的时候,就说明找到最小值了
        return nums[l];
    }
};

拓展

和33.搜索旋转排序数组的不同之处

  • 此题的targe相当于一个未知的最小值,所以不需要和nums[mid]比较大小,可以根据mid位置直接确定下一个区间

  • 33题的target是确定的,就算知道了mid的位置,还需要比较target和nums[mid]的大小,才能确定下一个区间

    • 在mid的某些情况下,target是可能出现在两个区间的

      就那上面的左图分析,如果mid在2处,target>nums[mid],target是可能出现在mid的左右两个区间的

    所以和左端 or 右端比较都可以,因为根据mid位置是无法直接确定下个区间的


和154. 寻找旋转排序数组中的最小值 II的不同之处

  • 154题中,数组内可能有重复的数值,那么num[r]==num[mid]时,是无法确定mid执行的是1处还是2处
  • 但是可以将r-1,因为如果num[r]是最小值,那么num[mid]也是最小值,不会影结果

你可能感兴趣的:(LeetCode刷题,c++,刷题,二分法)