0
点赞
收藏
分享

微信扫一扫

[LeetCode]Search in Rotated Sorted Array II


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 条评论