[leetcode 81] Search in Rotated Sorted Array II

来源:互联网 发布:js offsetwidth 编辑:程序博客网 时间:2024/06/10 17:01
题目描述:

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Write a function to determine if a given target is in the array.


The array may contain duplicates.


解题思路(1):题目要求我们找到具体的值,最简单的方法肯定是扫描一遍,然后就找到了,于是我们的事件复杂度是0(n),但是放在这里肯定有更好的方法。我们可以找到转折的那个点比如4,5,6,7,0,1,2转折点是7,7左边都比4(最左边)小,7的右边都比4小。二分可以找到,找到这个点之后,后面的就好办了,我们拆成了俩个有序的数组,每一个再用二分方法来查找,最后的结果时间复杂度为0(log^{n} ).下面我说一下如何二分找到那个关键点位置,当num[mid]对应的值比最左边值大的时候,转折点肯定在右边,那么将left改为mid+1,当num[mid]对应的值比最左边值小的时候,转折点肯定在左边,这时将right = mid-1,当等于的时候,left++,那么出来while循环,找到的就是转折点的位置.


解题思路(2):本题采用二分法实现,但是比较挠头的是边界问题,而且元素有重复,相比纯粹递增的数组难度要大得多,要解决这个问题,首先要对所有可能情况进行分类,然后对每种可能的类别进行相应的处理,本题的类别可以表示为下面的趋势图


暂且不考虑nums[mid] = nums[left]的情况,本题大致可以简化为上图两种情况,可能的情况划分出来,那么解决本题就比较容易了:

当 nums[mid] = nums[left] 时,这时由于很难判断 target 会落在哪,那么只能采取 left++

当 nums[mid] > nums[left] 时,这时可以分为两种情况,判断左半部比较简单(如果target不在左边这部分,那么我们是可以直接去掉左边这部分的)

当 nums[mid] < nums[left] 时,这时可以分为两种情况,判断右半部比较简单(如果target不在右边这部分,那么我们也是可以直接去掉右边这部分的)

C++代码如下:

作者:忆臻链接:https://zhuanlan.zhihu.com/p/24973495来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。class Solution {public:    bool search(vector<int>& nums, int target) {        //扫描一遍肯定可以,那么放在这里不是这么简单的,是希望我们用log级别的        //方法一我们先用师兄的做法,先二分找到那个边界,然后分开进行二分查找即可~        //方法二用下面这种方法                int len = nums.size();        int left = 0,right = len-1;        while(left<=right)        {            int mid = (left+right)/2;            if(nums[mid] == target)            {                return true;            }            if(nums[mid]==nums[left])                left++;            else if(nums[mid]>=nums[left])        //砍掉的一半一定要是可以砍掉的                {                    if(target<=nums[mid]&&target>=nums[left])                        right = mid-1;                    else                        left = mid+1;                                    }            else            {                if(nums[mid]< target&&target<=nums[right])                    left = mid+1;                else                    right = mid-1;            }        }        return false;    }};
python代码:
作者:忆臻链接:https://zhuanlan.zhihu.com/p/24973495来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。class Solution(object):    def search(self, nums, target):        """        :type nums: List[int]        :type target: int        :rtype: bool        """        left = 0        right = len(nums)-1                while left<=right:            mid = (left + right)/2            if nums[mid] == target:                return True            if nums[mid] == nums[left]:                left +=1            elif nums[mid] > nums[left]:                    #这样就是有序了                if target<nums[mid] and target>=nums[left]:                    right = mid-1                else:                    left = mid+1            else:                if target > nums[mid] and target<=nums[right]:                    left = mid+1                else:                    right = mid-1        return False

知乎主页:忆臻

专栏地址:机器学习算法

博客地址:忆臻博客





0 0