边界条件真复杂。结合剑指 Offer 11. 旋转数组的最小数字 | Cinte's Leetcode Record思考
继续结合套路【旋转数组】从易到难,各个击破! - 搜索旋转数组 - 力扣(LeetCode) (leetcode-cn.com)
对于一个旋转数组,分为2种,一种是出于旋转节点右边,一种是处于旋转节点左边。
当arr[lo] == arr[target]
时,直接返回
当arr[mid] < arr.back()
时,处于旋转节点右边
arr[mid] > target
: 此时target
必定处于旋转节点右边一部分,那么hi = mid - 1
arr[mid] < target
: 此时target
有两种情况
target >= arr[0]
: 表示了target
处于0 ~ mid
,则hi = mid - 1
target < arr[0]
: 表示了target
处于mid ~
,则lo = mid + 1
当arr[mid] > arr.back()
时,处于旋转节点左边
arr[mid] < target
: 此时target
必定位于旋转节点左边,是lo = mid + 1
arr[mid] > target
: 此时target
有两种情况
target >= arr[0]
: 表示了target
处于0 ~ mid
,则hi = mid - 1
target < arr[0]
: 表示了target
处于mid ~
,则lo = mid + 1
重点
arr[mid] == target
时,hi = mid
,使其向左缩
重点2
当arr[mid] == arr.back()
时,存在2种不确定的可能,对于这种情况需要单独处理,做法就是收缩区间。
那收缩区间是收缩lo
还是hi
呢,这里选择移动lo
,因为所求的是最左的边界值,如果在前面没有返回的话,说明arr[lo]
必定小于target,所以++lo
后是安全的。
由此便可以进行二分查找
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| class Solution { public: int search(vector<int>& arr, int target) { int lo = 0, hi = arr.size() - 1; while(lo <= hi) { if(arr[lo] == target) return lo; int mid = lo + (hi - lo) / 2; if(arr[mid] == target) hi = mid; else if(arr[mid] < arr.back()) { if(arr[mid] > target) hi = mid - 1; else { if (target >= arr[0]) hi = mid - 1; else lo = mid + 1; } }else if(arr[mid] > arr.back()) { if(arr[mid] < target) lo = mid + 1; else { if(target >= arr[0]) hi = mid - 1; else lo = mid + 1; } }else ++lo; } return -1; } };
|
review
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| class Solution { public: int search(vector<int>& arr, int target) { size_t lo{0}, hi{arr.size()}; while(lo < hi) { auto mid{lo + (hi - lo) / 2}; if(arr[lo] == target) return lo; if(arr[mid] > arr.back()) { if(arr[mid] < target) lo = mid + 1; else { if(target > arr.back()) hi = mid; else lo = mid + 1; } }else if(arr[mid] < arr.back()){ if(arr[mid] >= target) hi = mid; else { if(target > arr.back()) hi = mid; else lo = mid + 1; } }else ++lo; } return (hi == arr.size() || arr[hi] != target) ? -1 : hi; } };
|