zoukankan      html  css  js  c++  java
  • Find Minumu in Rotated Sorted Array

    https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/

    对于一个有序数组,将其元素以某一个元素为轴进行旋转,比如[0,1,2,3,4,5,6,7]可能会变成[4,5,6,7,0,1,2,3]
    求这个经过旋转的数组的最小值,这里假设数组中没有重复值

    二分查找

    • 可以看到,对于一个经过旋转的数组,[4,5,6,7,0,1,2,3] 其最小元素的左右两边都是有序的,如果对于某个元素,存在 nums[i] > nums[i-1],那么最小的元素就在 i 处
    • 因此,可以通过二分查找来解决,mi = (lo+hi)>>1,如果nums[mi] < nums[hi],则说明从 mi - hi之间都是有序的,因此逆序存在左边,因此需要把hi往左压缩
    • 反之,则说明逆序在右边,即左边是有序的,因此需要把lo往右压缩
    class Solution {
    public:
        int findMin(vector<int>& nums) {
            int lo = 0, hi = nums.size()-1;
            while(lo < hi)
            {
                int mi = (lo + hi)>>1;
                if(nums[mi] < nums[hi])
                    hi = mi;
                else
                    lo = mi+1;
            }
            return nums[lo];
        }
    };
    

    时间复杂度 (O(logN))


    求这样一个数组的最大值

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

    • 实际上,上面两个算法求的是逆序对的位置,而逆序对的位置可以用左边的元素来表示,也可以用右边的元素来表示,左边的元素就是最大值,右边的元素的就是最小值;
    • 因此,如果要求最大值,我们要把 lo 和 hi 尽可能往左靠,即 lo = mi, hi = mi-1
    • 如果要求最小值,我们要把 lo 和 hi 尽可能往右靠,即 lo = mi + 1, hi = mi

    相关问题,如果数组中存在相同的元素 https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii

  • 相关阅读:
    第二章:列表简介
    第三章:shell变量知识进阶
    第二章:shell变量
    WEB服务器
    第一章:变量和简单的数据类型
    第一节:python基础
    第一章:shell脚本初入门
    vim命令
    知识点一:OSI模型初识
    知识点二:HTTP超文本文件传输协议
  • 原文地址:https://www.cnblogs.com/qiulinzhang/p/12527472.html
Copyright © 2011-2022 走看看