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


    一个不包含重复元素的升序数组在经过旋转之后,可以得到下面可视化的折线图:

    fig1

    其中横轴表示数组元素的下标,纵轴表示数组元素的值。图中标出了最小值的位置,是我们需要查找的目标。

    我们考虑数组中的最后一个元素 x:在最小值右侧的元素(不包括最后一个元素本身),它们的值一定都严格小于 x;而在最小值左侧的元素,它们的值一定都严格大于 x。因此,我们可以根据这一条性质,通过二分查找的方法找出最小值。

    在二分查找的每一步中,左边界为 low,右边界为 high,区间的中点为 pivot,最小值就在该区间内。我们将中轴元素 nums[pivot] 与右边界元素 nums[high] 进行比较,可能会有以下的三种情况:

    第一种情况是 nums[pivot]<nums[high]。如下图所示,这说明 nums[pivot] 是最小值右侧的元素,因此我们可以忽略二分查找区间的右半部分。

    fig2

    第二种情况是 nums[pivot]>nums[high]。如下图所示,这说明 nums[pivot] 是最小值左侧的元素,因此我们可以忽略二分查找区间的左半部分。

    fig3

    由于数组不包含重复元素,并且只要当前的区间长度不为 1,pivot 就不会与 high 重合;而如果当前的区间长度为 1,这说明我们已经可以结束二分查找了。当二分查找结束时,我们就得到了最小值所在的位置。

    写法一:

    class Solution {
    public:
        int findMin(vector<int>& nums) {
            int n = nums.size();
            int l = 0, r = n - 1;
            while(l < r) {
                int mid = l + r >> 1;
                if(nums[mid] > nums[r]) l = mid + 1;
                else r = mid;
            }
            return nums[l];
        }
    };
    

    写法二:

    class Solution {
    public:
        int findMin(vector<int>& nums) {
            int n = nums.size();
            int l = 0, r = n - 1;
            while(l < r) {
                int mid = l + r >> 1;
                if(nums[mid] < nums[r]) r = mid;
                else l = mid + 1;
            }
            return nums[l];
        }
    };
    
  • 相关阅读:
    [cocos2dx 3.0 + xcode]疑难点记录
    [转]全球付虚拟卡申请流程~
    [转]全球付虚拟卡申请开发者账号的流程~
    [cocos2d-x3.0]Android+NDK+Eclipse环境搭建及编译步骤~
    Torque2D MIT 学习笔记(27) ---- ImageFont的使用以及字体ImageAsset的工具生成
    关于拒绝测试驱动开发(NoTDD)
    工作两年随感
    一个Java应用,三种字体风格(Java, Windows, Mac),真是蛋疼
    看看这蛋疼的Java代码
    Bash实用技巧:同时循环两个列表
  • 原文地址:https://www.cnblogs.com/fxh0707/p/15036862.html
Copyright © 2020-2023  润新知