Leetcode 33:搜尋旋轉排列陣列(最詳細的解法!!!)
阿新 • • 發佈:2018-12-16
假設按照升序排序的陣列在預先未知的某個點上進行了旋轉。
( 例如,陣列 [0,1,2,4,5,6,7]
可能變為 [4,5,6,7,0,1,2]
)。
搜尋一個給定的目標值,如果陣列中存在這個目標值,則返回它的索引,否則返回 -1
。
你可以假設陣列中不存在重複的元素。
你的演算法時間複雜度必須是 O(log n) 級別。
示例 1:
輸入: nums = [4,5,6,7,0,1,2], target = 0
輸出: 4
示例 2:
輸入: nums = [4,5,6,7,0,1,2], target = 3
輸出: -1
解題思路
由於問題給定的時間複雜度要求是O(logn)
級別,所以你當然不能通過直接遍歷得到。我們首先想到的是通過二分搜尋法,但是這裡的二分搜尋法需要一些變化。對於第一個例子來說
4 5 6 7 0 1 2
l m r
我們首先計算nums[m]=7
,然後比較nums[m]>=nums[l]
,如果成立,說明[l:m]
這個區間正常。我們先要在[l:m]
這個區間找target
,也就是我們要判斷nums[l]<=target<=nums[m]
,如果成立說明在這個區間內,我們讓r=m-1
,否則的話l=m+1
。
4 5 6 7 0 1 2
l m r
回到上一步nums[m]>=num[l]
成立,nums[l]<=target<=nums[m]
r=m-1
4 5 6 7 0 1 2
l
r
m
此時l==r
,而target=0
,即返回m
。
如果我們發現nums[m]<nums[l]
,說明[m:r]
這個區間正常。例如
5 6 7 0 1 2 4
l m r
我們就要先判斷target
是不是在[m:r]
這個區間內,也就是判斷nums[m]<=target<=nums[r]
,如果成立l=m+1
,否則的話r=m-1
。
總體的思路就是先找出中間元素,然後判斷左右哪個是標準空間(排好序的空間),接著判斷元素是不是在標準空間中(因為這是可以確定的)。接著繼續回到之前步驟,直到找到為止。
class Solution:
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if not nums:
return -1
low, high = 0, len(nums) - 1
while low <= high:
mid = (low + high) // 2
if target == nums[mid]:
return mid
if nums[low] <= nums[mid]:
if nums[low] <= target <= nums[mid]:
high = mid - 1
else:
low = mid + 1
else:
if nums[mid] <= target <= nums[high]:
low = mid + 1
else:
high = mid - 1
return -1
其實就是二分搜尋的泛化。
reference:
如有問題,希望大家指出!!!