81. 搜索旋转排序数组 II

题目描述

假设按照升序排序的数组在预先未知的某个点上进行了旋转。(例如,数组[0,0,1,2,2,5,6]可能变为 [2,5,6,0,0,1,2])。

编写一个函数来判断给定的目标值是否存在于数组中.若存在返回true,否则返回false.

示例 1:

输入: nums = [2,5,6,0,0,1,2], target = 0
输出: true
示例 2:

输入: nums = [2,5,6,0,0,1,2], target = 3
输出: false
进阶:

这是搜索旋转排序数组的延伸题目,本题中的nums可能包含重复元素。这会影响到程序的时间复杂度吗?会有怎样的影响,为什么?

思路

根据mid位于前半段还是后半段,mid的划分会造成局部单调性,目标在这个单调区间中,搜索转向这个区间。目标不在这个单调范围中,则可以排除这个单调区间,搜索转向另半个区间

如果这个条件成立:nums[l]==nums[mid] && nums[mid]==nums[r],则我们无法判断mid到底是位于前半段,还是后半段,我们可以举出这种情况下,mid在前半段实际例子又可以举出在后半段的实际例子
如果这个条件不成立,则我们可以判断mid到底是位于前半段还是后半段。论证过程可以使用反证法进行证明。例如,if(nums[mid]<=nums[r]),我们可以得出右边有序,mid位于后半段,此时假如mid位于前半段,则:

  • nums[mid]>=nums[r](前半段的元素都大于后半段的元素),而if(nums[mid]<=nums[r]),所以nums[mid]==nums[r].
  • 而假如mid位于前半段,则此时前半段有序,nums[mid]>=nums[l],而nums[l]>=nums[r](前半段的元素都大于后半段的元素),所以nums[mid]>=nums[l]>=nums[r],而nums[mid]==nums[r],所以nums[mid]==nums[l]==nums[r],矛盾.

这是在整个数组还是存在两个不同的有序子数组的情况下,程序逻辑无误。当已经为一个单独的有序数组时,if(nums[mid]<=nums[r]),我们仍然可以得出右边有序,然后进行下面的排查这个有序范围的操作。
总之,无论整个数组是存在两个不同的有序子数组的情况,还是已经是单独的有序数组的情况,我们都可以进行这个排查有序范围的操作

代码

class Solution {
public:
    bool search(vector<int>& nums, int target) {
        
        int n = nums.size();
        int l=0;
        int r=n-1;
        while(l<=r)
        {

            int mid=l+(r-l)/2;
            if(nums[mid]==target)
                return true;
	    //如果这个条件成立,则我们无法判断mid到底是位于前半段,还是后半段,所以
	    //为了后面算法的设施,需要首选进行判断,排除
            if(nums[l]==nums[mid] && nums[mid]==nums[r])
            {            
                l++;    
                r--;
            //因为经过上面的判断A[mid]!=target,所以A[l],A[r]都可以从搜索范围中排除掉
            }
            else//下面的情况是能够确定mid位于旋转数组的那一段的情况
            {   
                if(nums[mid]<=nums[r])//右边有序
                {
                    if(nums[mid]<target && target<=nums[r])
                        l=mid+1;
                    else
                        r=mid-1;//排除掉
                }
                else if(nums[l]<=nums[mid])//左边有序
                {
                    if(nums[l]<=target && target<nums[mid])
                        r=mid-1;
                    else
                        l=mid+1;//排除掉
                }

            }
           
        }
         
        return false;
    }
};

posted on 2021-05-01 16:09  朴素贝叶斯  阅读(38)  评论(0编辑  收藏  举报

导航