Question:
思路:
This question generally have two situations, when we rotate a sorted array, we normally would have array in this shape. Where F is normal right part of original array. S is the rotated part of original left part array
So, this questions becomes we need to find target inside two sorted array. So, which sorted array does target locate in? We can’t just simply compare target value with nums[mid] because we don’t know how the array is rotated, so it means if target < nums[mid]. target could be located on the left side of nums[mid](in F) but it also could be located on the right side of nums[mid] (in S), so we need to first find out which array, F or S that target locate and mid locate.
So, normally if mid locate in F, that means nums[low] < nums[mid], but if mid locate in S, then nums[low] > nums[mid] (because nums[low] > every element reside in S)
Also, we can determine whether target reside on F or S using the same way as comparing with nums[low].
Til here, we found the out where target and nums[mid] locate. Then we can 分类讨论. If target 和 mid 在同一个F or S底下. 那么,…… 如果他们分别在不同的sorted array底下, 那么…… 分类讨论就简单了.
注意, 还有一种特殊情况. 就是当nums[low] == nums[mid]的时候, 这是个无解. 因为如果这俩相同(题目允许duplicated) 那么我们无法判断mid 是在F还是在S. 就我们没法判断这个array是rotated 过还是没rotate过. ex:
[1,1,1,1,1,3,4,5,6] → mid 在 original array 的 S
[5,5,5,5,5,6,1,2,3,4] → mid 在 original array 的F
所以就没法判断target的relative position. 那就没法做了.
```class Solution {
public boolean search(int[] nums, int target) {
int low = 0;
int high = nums.length-1;
while(low < high){
int mid = (low+high)>>1;
if(nums[mid] == target) return true;
// if nums[start]==nums[mid], means we are not sure wether mid belongs to left or right, so we just carefully shrink the window by size 1.
if (nums[low] == nums[mid]) {
low++;
continue;
}
// which array does mid belong to.
// if nums[start] < nums[mid] means mid is in the left array, else if nums[start] > nums[mid] means mid is located in rotated part of array
boolean midExistInFirst = nums[low] <= nums[mid];
boolean targetExistInFirst = nums[low] <= target;
if(midExistInFirst == targetExistInFirst){
if(nums[mid] < target){
low = mid + 1;
} else{
high = mid;
}
}
else{
if(midExistInFirst){
low = mid + 1;
} else{
high = mid;
}
}
}
return nums[low]==target;
}
}