給定一個升序排序後在某個未知點旋轉的數組(如 [4,5,6,7,0,1,2]),搜索目標值 target,返回索引,不存在返回 -1。要求 O(log n) 時間複雜度。
旋轉數組雖非整體有序,但分為兩個有序子數組。二分查找關鍵在於判斷 mid 落在哪個有序部分,並據此決定搜索方向。
數組:[4, 5, 6, 7, 0, 1, 2]
↑ ↑ ↑
left mid right
情況 1:nums[mid] >= nums[left] → 左半部分有序
- 若 target 在 [nums[left], nums[mid]) → right = mid - 1
- 否則 → left = mid + 1
情況 2:nums[mid] < nums[left] → 右半部分有序
- 若 target 在 (nums[mid], nums[right]] → left = mid + 1
- 否則 → right = mid - 1
class Solution {
public:
int search(vector& nums, int target) {
int len = nums.size();
if (len == 0) return -1;
if (len == 1) return nums[0] == target ? 0 : -1;
int left = 0, right = len - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
// 早期命中優化
if (nums[mid] == target) return mid;
if (nums[left] == target) return left;
if (nums[right] == target) return right;
if (nums[mid] >= nums[left]) { // 左半有序
if (target > nums[left] && target < nums[mid])
right = mid - 1;
else
left = mid + 1;
} else { // 右半有序
if (target > nums[mid] && target < nums[right])
left = mid + 1;
else
right = mid - 1;
}
}
return -1;
}
};
nums[mid] >= nums[left] 是關鍵判斷< 和 ≤,避免死循環nums[left] == nums[mid] == nums[right] 情況nums[mid] 與 nums[right]
測試用例全通過,執行時間擊敗 90%+ 提交。