难点在于确定往数组的哪一半段继续二分查找 设起点、中间点、终点分别为 start、middle、end (採用前闭后开的区间表示方法 假设target = A[middle] return middle 假设A[middle] >= A[start],则[start,middle)单调递增 1.假设target < A[middle] && target >= A[start],则 end = middle 2.start = middle + 1, otherwise 假设A[middle] < A[start]。则[middle,end)单调递增 1.假设target > A[middle] && target <= A[end - 1],则 start = middle + 1 2.end = middle, otherwise
Explanation
My solutions use binary search guided by the following thoughts:
Remember the array is sorted, except it might drop at one point.
If nums[0] <= nums[i], then nums[0..i] is sorted (in case of "==" it's just one element, and in case of "<" there must be a drop elsewhere). So we should keep searching in nums[0..i] if the target lies in this sorted range, i.e., if nums[0] <= target <= nums[i]. If nums[i] < nums[0], then nums[0..i] contains a drop, and thus nums[i+1..end] is sorted and lies strictly between nums[i] and nums[0]. So we should keep searching in nums[0..i] if the target doesn't lie strictly between them, i.e., if target <= nums[i] < nums[0] or nums[i] < nums[0] <= targetThose three cases look cyclic:
nums[0] <= target <= nums[i] target <= nums[i] < nums[0] nums[i] < nums[0] <= targetSo I have the three checks (nums[0] <= target), (target <= nums[i]) and (nums[i] < nums[0]), and I want to know whether exactly two of them are true. They can’t all be true or all be false (check it), so I just need to distinguish between “two true” and “one true”. Parity is enough for that, so instead of adding them I xor them, which is a bit shorter and particularly helpful in Java and Ruby, because those don’t let me add booleans but do let me xor them.
(Actually while developing this I thought of permutations of nums[0], target and nums[i] and the permutation parity and saw those three checks as representing inversions, but I had trouble putting that into words and now find the above explanation much better. But it helped me get there, so I wanted to mention it here.)
【转发1】