与中间值比较,分前半段有序和后半段有序分别判断。比有序的二分查找多一些判定条件。
1、 要么前半段有序,要么后半段有序。
2、 当前半段有序时:即循环数组中间值比循环数组最左边值大 则 nums[left] <= nums[mid]
当target 比中间值小,比最左值(前半段最小值)大时,肯定在前面部分 则high = mid - 1 。
如果不在前半段,可能在后半段,low = mid + 1。
3、同理后半段也一样。
ps:分前半段有序后半段有序时,当nums[left] <= nums[mid] 则 left到mid有序。
否则 mid到right 有序。
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while(left <= right){
int mid = (right - left)/2 + left;
if(nums[mid] == target) return mid;
// 中间值不是要求值
if(nums[left] <= nums[mid]){ // 前半段 有序left 到 mid
if(nums[left] <= target && target < nums[mid]){
// 中间值 大于目标值, 目标值大于最左边值 肯定在前半段
right = mid - 1;
}
else{ // 否则重新找
left = mid + 1;
}
}
else{ // 前半段无序,后半段有序 mid到right
if(nums[mid] < target && target <= nums[right]){
left = mid + 1;
}
else {
right = mid - 1;
}
}
}
return -1;
}
};
京公网安备 11010502036488号