zoukankan      html  css  js  c++  java
  • LeetCode81:搜索旋转排序数组 II 与 LeetCode154:寻找旋转排序数组中的最小值 II

    在看剑指offer时遇到了这个题目:寻找旋转排序数组中的最小值 II

    假设按照升序排序的数组在预先未知的某个点上进行了旋转。

    ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

    请找出其中最小的元素。

    注意数组中可能存在重复的元素。

    看到这个题目第一时间就想起了LeetCode81:搜索旋转排序数组 II。

    首先先看看这两个题目的共同点:都是带有重复元素的旋转排序数组。

    但他们的不同点在于:81题是寻找指定的数字,也就是说,这个target值得位置是不定的,它既可能位于左边的升序数组,也可能位于右边的升序数组。

    而对于154题来说,这个target位置是固定的,这个值是旋转前数组的第一个值,旋转后它一定位于右边的升序数组。

    这也就是这两个题目的最大的区别,对于81题来说,我们要不断通过判断left和righ与mid的值来缩小搜索空间直至寻找到。

    而对于154题来说,我们只需要进行right和mid的对比,因为我们的target位于右边的升序数组,所以我们一切工作的目的也就是将搜索区间夹逼到右边数组。

    如果在154题我们引入left与mid进行大小判断,这是无意义的,因为当nums[left]<nums[mid]时我们无法判断这个时候是left和mid两个都位于左边的升序数组还是右边的升序数组。

    而对于right,如果mid的值小于right,说明一定在右边的升序数组,此时让right=mid来缩小夹逼范围(如果right=mid-1可能会错过)

    而如果mid的值大于right,说明mid一定在左边,则令left=mid+1。

    而如果mid==right的值,只要让right--,能继续循环即可以.

    另外剑指offer在这个题里,当遇见相等时使用的是线性搜索。

    class Solution {
    public:
        int minNumberInRotateArray(vector<int> rotateArray) {
    		auto& nums=rotateArray;
    		int low=0,high=nums.size()-1;
    		int mid=low;
    		while(low<high)
    		{
    			mid=(low+high)/2;
    			if(nums[mid]<nums[high])
    				high=mid;
    			else if(nums[mid]>nums[high])
    				low=mid+1;
    			else
    				high--;
    		}
    		return nums[low];
    	}
    };
    

     从这两个题目里可以了解到,对于这种二分查找的题目,更重要的是根据target来调整夹逼搜索范围,比如154中已知target一定位于右边的升序数组,则只要与right对比就可以了。

  • 相关阅读:
    第2章安装和升级MySQL
    1.7.3.4 ENUM和SET约束
    1.7.3.3对无效数据的强制约束
    1.7.3.2外部关键约束
    跨浏览器的事件处理程序-读书笔记
    表单-读书笔记
    【小知识点】一条线的居中问题
    函数表达书-读书笔记
    原型链-读书笔记
    面向对象(三)-读书笔记
  • 原文地址:https://www.cnblogs.com/lxy-xf/p/11337835.html
Copyright © 2011-2022 走看看