[LeetCode]Search in Rotated Sorted Array II

来源:互联网 发布:2017eia原油库存数据 编辑:程序博客网 时间:2024/06/05 17:22

Question
Follow up for “Search in Rotated Sorted Array”:
What if duplicates are allowed?

Would this affect the run-time complexity? How and why?

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


本题难度Medium。

【复杂度】
时间 O(N) 空间 O(1)

【思路】
本题是Search in Rotated Sorted Array的变形。在Search in Rotated Sorted Array中可以通过nums[start]<=nums[mid]nums[mid]<=nums[end]判断两边是否为有序。但是在这里出现一个问题:比如左半边,如果nums[start]==nums[mid]它是有序吗?对于:

    [1 3 1 1 1]

左半边为1 3 1,符合条件但并不有序。不过如果nums[start]<nums[mid],那么左半边仍然是有序的。因此,我们列出三种情况进行处理:

  1. 左半边有序。如果target在左半边范围内就只搜索左半边,否则只搜索右半边
  2. 右半边有序。如果target在右半边范围内就只搜索右半边,否则只搜索左半边
  3. 都不是。两边都要分别搜索

其本质就是增加了对第三种情况的处理(29-34行)

【注意】

  1. 我们在判断是否为有序时,比如对于左半边是:nums[start]<nums[mid],不要写成nums[start]<nums[mid-1],这样有可能导致mid-1<0超过范围

  2. 在判断是否在其范围内,比如左半边是:nums[start]<=target&&target<nums[mid]不要写成target<nums[mid]只判断一边,例如:

     [4 5 6 1 2 3],target=3

    左半边为4 5 6,有序,而且3<6,但3不在左半边。而对于有序数列而言,如果target<nums[mid],target是不可能再出现在右半边,所以可以单边判断。

【代码】

public class Solution {    public boolean search(int[] nums, int target) {        //require        int size=nums.length;        if(size<1)            return false;        //invariant        return helper(0,size-1,nums,target);    }    private boolean helper(int start,int end,int[] nums, int target){        //base case        if(end<start)            return false;        int mid=(start+end)/2;        if(nums[mid]==target)            return true;        if(nums[start]<nums[mid]){            if(nums[start]<=target&&target<nums[mid])                return helper(start,mid-1,nums,target);            else                return helper(mid+1,end,nums,target);        }else if(nums[mid]<nums[end]){            if(nums[mid]<target&&target<=nums[end])                return helper(mid+1,end,nums,target);            else                return helper(start,mid-1,nums,target);        }else{            if(helper(start,mid-1,nums,target))                return true;            else                return helper(mid+1,end,nums,target);        }    }}

参考

Java 1ms binary search solution with comments

public class Solution {    public boolean search(int[] nums, int target) {        // note here end is initialized to len instead of (len-1)        int start = 0, end = nums.length;        while (start < end) {            int mid = (start + end) / 2;            if (nums[mid] == target) return true;            if (nums[mid] > nums[start]) { // nums[start..mid] is sorted                // check if target in left half                if (target < nums[mid] && target >= nums[start]) end = mid;                else start = mid + 1;            } else if (nums[mid] < nums[start]) { // nums[mid..end] is sorted                // check if target in right half                if (target > nums[mid] && target < nums[start]) start = mid + 1;                else end = mid;            } else { // have no idea about the array, but we can exclude nums[start] because nums[start] == nums[mid]                start++;            }        }        return false;    }}
0 0