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  可能包含重复元素。

这会影响到程序的时间复杂度吗?会有怎样的影响,为什么?

 

思路:请先参考33.搜索旋转排序数组, 如果数组中有重复元素的情况存在的话,那么33题中,直接二分找最大值的方法就不成立了。比如说数组是2 2 2 2 0 1,或者是3 4 2 2 2 2,可能出现中心点左侧,也可能是右侧。 所以要先做一个预处理,先把两侧重复的元素截断,再按照33题中的方法去找最大值坐标。找到该点在中心点左侧或者是右侧之后,剩下的二分查找目标值的做法就是一样的了。平均时间复杂度可以达到O(logn),最坏时间复杂度O(n)。

class Solution {
public:
    bool search(vector& nums, int target) {
        if (nums.empty()) return false;
        int l = 0, r = nums.size() - 1, l1, r1, flag = -1, i; //flag记录数组中最大值坐标
        while (l <= r){
            //预处理
            if (nums[l] == target || nums[r] == target) return true;
            for (i = l; i  l && nums[i] == nums[i-1]; --i);//截断右边所有重复的
            r = i;
            //剩下做法就和33题一样了
            int mid=(l+r)/2;
            if(nums[mid] > nums[l]) l=mid;
            else if(nums[mid] < nums[l]) r=mid-1;
            else break;
        }
        if(target < nums[0]){
            l1=l+1;
            r1=nums.size()-1;
        }
        else{
            l1=0;
            r1=l;
        }
        while(l1<=r1){
            int mid1=(l1+r1)/2;
            if(nums[mid1] target) r1=mid1-1;
            else return mid1;
        }
        return false;
    }
};

 

你可能感兴趣的:(leetcode)