剑指 Offer 11(154. 寻找旋转排序数组中的最小值 II). 旋转数组的最小数字(实为Hard)

实为Hard

首先这个题有一些很简单的解法,例如优先队列(选择小根堆),再返回第一个值,就得到了解。但是本题要求运用二分查找。

代码:

 int minArray(vector<int>& numbers) {
        int left=0;
        int right=numbers.size()-1;
       while(left<right)
       {
           int mid=left+(right-left)/2;
           if(numbers[mid]>numbers[right])
           {
               left=mid+1;continue;
           }
           else if(numbers[mid]<numbers[right])
           {
               right=mid;continue;
           }
           else
           {
               right--;
           }
       }
        return numbers[left];
    }

首先应该寻找规律解题:

下面我们以1 2 3 4 5这个升序数组为例

vector<int>&  nums

旋转之后可能为:

1  2  3  4  5

2  3  4  5  1

3  4  5  1  2

4  5  1  2  3

5  1  2  3  4

首先理解二分查找,需要用到数组中间值nums[mid],再结合旋转数组的局部有序。

可以分析出来如果nums[mid]>nums[right],那么最小值一定在nums[mid+1]到nums[right]之间。

如果nums[mid]<nums[right],那么最小值一定在nums[left]到nums[mid]之间

        首先分析到这个地方,大家一定有疑问:为什么一个是mid+1,一个是mid。

我的分析是,如果nums[mid]<nums[right]时,nums[mid]有可能是最小值,不能直接舍弃。

而nums[mid]>nums[right]时,nums[mid]不可能是最小值,可以直接舍弃。

如果nums[mid]==nums[right],那么就把最后值nums[right]舍弃了,将right更新成right-1。

猜你喜欢

转载自blog.csdn.net/qq_51710331/article/details/125174182