LeetCode - Search in Rotated Sorted Array(在旋轉排序陣列中搜尋)
題目描述
給定一個已按升序排列的整數數組 nums
,它被旋轉過一次或多次。給定一個目標值 target
,如果目標值存在於數組中,則返回其索引;否則返回 -1
。你可以假定數組中的所有值是唯一的。
範例:
1
2
3
4
5
6
7
8
輸入:nums = [4,5,6,7,0,1,2], target = 0
輸出:4
輸入:nums = [4,5,6,7,0,1,2], target = 3
輸出:-1
輸入:nums = [1], target = 0
輸出:-1
限制:
1 <= nums.length <= 5000
-10^4 <= nums[i] <= 10^4
nums
中的所有值互不相同nums
是一個升序排列的數組,並在某個點上進行了旋轉
解法思路
由於數組是有序的且被旋轉過,我們可以使用二分查找來實現 O(log n) 的時間複雜度。通過二分查找中的判斷邏輯,可以確定 target
是否位於旋轉過後的有序段中。
二分查找步驟:
- 設置
left
和right
指針分別指向數組的起點和終點。 - 計算中間位置
mid
並比較nums[mid]
與target
。 - 根據旋轉排序數組的特性進行判斷:
- 若
nums[mid]
等於target
,則返回mid
。 - 確定哪一側是有序的:
- 如果
nums[left] <= nums[mid]
,則左側是有序的。 - 如果
nums[mid] <= nums[right]
,則右側是有序的。
- 如果
- 在有序的一側查找
target
:- 若左側有序且
nums[left] <= target < nums[mid]
,則將right
移到mid - 1
。 - 若右側有序且
nums[mid] < target <= nums[right]
,則將left
移到mid + 1
。 - 否則,將搜索範圍縮小到無序的一側。
- 若左側有序且
- 若
- 若遍歷完畢未找到目標值,則返回
-1
。
代碼實現
以下是 Python 的實現:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def search(nums, target):
left, right = 0, len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
return mid
# 左側有序
if nums[left] <= nums[mid]:
if nums[left] <= target < nums[mid]:
right = mid - 1
else:
left = mid + 1
# 右側有序
else:
if nums[mid] < target <= nums[right]:
left = mid + 1
else:
right = mid - 1
return -1
代碼解析
- 初始化指針:
left
和right
指向數組的起點和終點。 - 二分查找:
- 若
nums[mid]
等於target
,則返回mid
。 - 若左側有序且
target
位於此區間內,則將right
設為mid - 1
。 - 若右側有序且
target
位於此區間內,則將left
設為mid + 1
。
- 若
- 返回結果:若遍歷完畢未找到
target
,則返回-1
。
時間和空間複雜度
- 時間複雜度:O(log n),每次迭代將範圍縮小一半。
- 空間複雜度:O(1),只使用了常數空間。
本文章以 CC BY 4.0 授權