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对比就可以了。

posted @ 2019-08-12 09:19  李湘沅  阅读(149)  评论(0编辑  收藏  举报