題目說明
給定一個原本升序排列、但被旋轉過的整數陣列 nums,以及一個目標值 target。
請你在陣列中找出 target 的索引,若不存在則回傳 -1。
演算法必須在 O(log n) 時間內完成。
範例
Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4
Input: nums = [4,5,6,7,0,1,2], target = 3
Output: -1
Input: nums = [1], target = 0
Output: -1
解題思路
這題是一個經典的 改良版二分搜尋 (Binary Search)。
雖然陣列被旋轉過,但可以發現:
至少有一半的區間仍然是「有序」的。
我們利用這個特性判斷 target 位於哪一邊。
解法邏輯:
設定左右指標 left = 0, right = nums.length - 1
當 left <= right:
取中間點 mid
若 nums[mid] == target,直接回傳 mid
若左半邊有序 (nums[left] <= nums[mid]):
若 target 位於 [nums[left], nums[mid]),則往左找
否則往右找
否則(右半邊有序):
若 target 位於 (nums[mid], nums[right]],則往右找
否則往左找
若找不到,回傳 -1
Java 程式碼
class Solution {
public int search(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
}
// 左半邊有序
if (nums[left] <= nums[mid]) {
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;
}
}
複雜度分析
時間複雜度:O(log n)
空間複雜度:O(1)
心得
這題其實是「二分搜尋」的變形版。
最關鍵的是理解:旋轉後的陣列仍保留部分有序結構,利用這點我們就能判斷搜尋方向。


