【剑指11】旋转数组的最小值

方法一:二分查找:时间O(logn),空间O(1)

题解:比较 mid 值和 right 的值分三种情况

  1. 若num[mid] < num[right],则 mid 和 right 处于同一个递增序列,也就是可以忽略右半区间。让right = mid,注意这里不能确定mid 处是不是最小值,因此不能是right = mid - 1
    在这里插入图片描述
  2. 若num[left] > num[right],则 mid 和 right 处于不同递增区间,[left, mid]之间不可能存在最小值,因此可以忽略左半区间,让 left = mid + 1,这里可以直接让left = mid + 1。
    在这里插入图片描述
  3. 若num[mid] == num[right],此时不能确定[left, right]之间是否存在最小值,因此right - -,下面只要证明right - -之后[left, right]之间存在最小值:设最小值位置为 x,若 x < right 则right - -后正确。若 x = right 则 num[mid] = num[right] = num[x] 则right - - 之后也正确
    在这里插入图片描述
    这里不用 left 作为参照是因为:无法确定第一次比较时,left 是在哪一个区间内,因此无法移动left 和 right 位置
class Solution {
    
    
public:
    int minArray(vector<int>& numbers) 
    {
    
    
        int left = 0, right = numbers.size() - 1;
        while (left <= right)
        {
    
    
            int mid = left + ((right - left) >> 1);
            // 1.说明可以忽略右区间
            if (numbers[mid] > numbers[right])
            {
    
    
                left = mid + 1;
            }
            // 2.说明可以忽略左区间
            else if (numbers[mid] < numbers[right])
            {
    
    
                right = mid;
            }
            // 3.不能判断mid 和 right中间是否存在最小值,因此right--
            else
            {
    
    
                right--;
            }
        }
        return numbers[left];
    }
};

猜你喜欢

转载自blog.csdn.net/qq_45691748/article/details/112445146
今日推荐