思路:
因为原数组是升序排列的。所以可以把数组分为两部分,一部分大于等于nums[0],另一部分小于nums[0]。
先通过一次二分找到第一个小于nums[0]的位置。
然后通过判断target和nums[0]的大小关系,判断是在左半部分还是右半部分。
再进行一次二分,最终找到答案。
总结:
二分的本质是两段性不是单调性。
代码:
class Solution {
public int search(int[] nums, int target) {
int n = nums.length;
int l = 0, r = n - 1;
// 先找到第一个小于nums[0]的位置
while(l <= r) {
int mid = l + (r - l)/2;
if(nums[mid] >= nums[0]) {
l = mid + 1;
}
else {
r = mid - 1;
}
}
//System.out.println(l);
// 然后判断在左半部分还是右半部分
if(target >= nums[0]) {
l = 0;
}
else {
r = n - 1;
}
// 对区间二分
while(l <= r) {
int mid = l + (r - l)/2;
if(nums[mid] < target) {
l = mid + 1;
}
else {
r = mid - 1;
}
}
return l < n && nums[l] == target ? l : -1;
}
}
参考: