二分查找4寻找旋转排序数组中的最小值 II(hard)

Posted 念奕玥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分查找4寻找旋转排序数组中的最小值 II(hard)相关的知识,希望对你有一定的参考价值。

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

在这里插入图片描述
分析:初始数组有序且元素不重复,要在数组中寻找是否存在目标值。
思路:用二分法查找。要始终将目标值(这里是最小值)放在left与right包围的区域中,并不断收缩左边界或右边界。此处因为对数组进行了旋转,所以需要自己判断目标值到底在哪一边。
目标值在左边,收缩right的情况:

  • nums[mid]<nums[left], nums[mid]<nums[right]
  • nums[mid]>nums[left],nums[mid]<nums[right]
    目标值在右边,收缩left的情况:
  • nums[mid]>nums[left], nums[mid]>nums[right]

另外,因为原始数组升序排列,因此无论怎么旋转都不会出现降序排列的情况,所以也就不会出现 nums[mid]<nums[left], nums[mid]>nums[right]的情况。
由以上分析可得,通过比较nums[mid]与nums[right]的大小,可以判断目标值在左侧还是右侧,进而去收缩区域。
如果是去比较nums[mid]与nums[left]的大小,则当nums[mid]<nums[left]时,无法判断是收缩right还是left。

class Solution {
    public int findMin(int[] nums) {
        int left=0,right=nums.length-1;
        //循环判断条件是<,避免出现mid与right指向同一元素的情况
        while(left<right){
            int mid = left+(right-left)/2;
            if(nums[mid]<nums[right]){
                right=mid;
            }else if(nums[mid]>nums[right]){
                left=mid+1;
            } 
        }
        return nums[left];
    }
}

while循环退出的条件:
若数组只有一个数,left == right,不会进入while循环,直接输出。
若数组多于一个数,循环到最后,会只剩两个数,nums[mid] == nums[left],以及nums[right],left == mid == right - 1。

  • 如果nums[left] == nums[mid] > nums[right],则左边大、右边小,
    需要执行left = mid + 1,使得left == right,左右边界位置重合,循环结束,nums[left]与nums[right]都保存了最小值。
  • 如果nums[left] == nums[mid] < nums[right],则左边小、右边大,
    会执行right = mid,使得left == right,左右边界位置重合,循环结束,nums[left]、nums[mid]、nums[right]都保存了最小值。

以上是关于二分查找4寻找旋转排序数组中的最小值 II(hard)的主要内容,如果未能解决你的问题,请参考以下文章

二分查找4寻找旋转排序数组中的最小值 II(hard)

154. 寻找旋转排序数组中的最小值 II(困难)-二分查找

寻找旋转排序数组中的最小值 II(数组二分查找)打印1000以内的所有素数,并从键盘输入一个正整数,判断是否为素数数组元素统计(算法初阶基础知识)

LeetCode.154 - 寻找旋转排序数组中的最小值 II(二分思想)

lintcode:寻找旋转排序数组中的最小值 II

Leetcode No.154 寻找旋转排序数组中的最小值 II(二分法)