一文解決 4 道 搜尋旋轉排序陣列 題

2022-05-01 22:00:15 字數 1714 閱讀 2838

**自:leetcode題解區-一文解決 4 道「搜尋旋轉排序陣列」題

可以分為 3 類:

題目要求時間複雜度$o(logn)$,顯然應該使用二分查詢。二分查詢的過程就是不斷收縮左右邊界,而怎麼縮小區間是關鍵。

如果陣列「未旋轉」,在陣列中查詢乙個特定元素target的過程為:

但是這道題,由於陣列「被旋轉」,所以左側或者右側區間不一定是連續的。在這種情況下,如何判斷target位於哪個區間?

首先,乙個重要的結論:將區間分均分,必然有一半有序,一半無序。問題是如何找到有序的那一半?

根據旋轉陣列的特性,當元素不重複時,如果nums[i] <= nums[j],說明區間[i,j]是「連續遞增」的

因此,在旋轉排序陣列中查詢乙個特定元素時:

否則,說明右側區間[mid,right]「連續遞增」。此時:

注意:區間收縮時不包含mid,也就是說,實際收縮後的區間是[left,mid)或者(mid,right]

可以很容易地寫出**:

int search(vector& nums, int target) 

else

}return -1;

}

這道題是 33 題的公升級版,元素可以重複。當nums[left] == nums[mid]時,無法判斷target位於左側還是右側,此時無法縮小區間,退化為順序查詢。

例如 [1, 3, 1, 1, 1]中查詢3,按原來的**就會出錯。

順序查詢的一種方法是直接遍歷[left,right]每一項:

if nums[left] == nums[mid] 

}

另一種方法是令left++,去掉乙個干擾項,本質上還是順序查詢:

if nums[left] == nums[mid]
其實這道題沒有低於o(n)的演算法,所以直接遍歷一遍即可。

如果陣列沒有翻轉,即nums[left] <= nums[right],則nums[left]就是最小值,直接返回。

如果陣列翻轉,需要找到陣列中第二部分的第乙個元素:

下面討論陣列翻轉的情況下,如何收縮區間以找到這個元素:

}這道題是 153 題的公升級版,元素可以重複。和 81 題一樣,當nums[left] == nums[mid]時,退化為順序查詢。

81 題提供了兩種方法:

154 題只能使用第一種方法。因為如果left是最小元素,那麼left++就把正確結果給跳過了。

演算法題 搜尋旋轉排序陣列

假設按照公升序排序的陣列在預先未知的某個點上進行了旋轉。例如,陣列 0,1,2,4,5,6,7 可能變為 4,5,6,7,0,1,2 搜尋乙個給定的目標值,如果陣列中存在這個目標值,則返回它的索引,否則返回 1。你可以假設陣列中不存在重複的元素。你的演算法時間複雜度必須是 o log n 級別。1 ...

每日一題 搜尋旋轉排序陣列

題目描述 假設按照公升序排序的陣列在預先未知的某個點上進行了旋轉。例如,陣列 0,1,2,4,5,6,7 可能變為 4,5,6,7,0,1,2 搜尋乙個給定的目標值,如果陣列中存在這個目標值,則返回它的索引,否則返回 1 你可以假設陣列中不存在重複的元素。你的演算法時間複雜度必須是 o log n ...

lintcode刷題 搜尋旋轉排序陣列

原題如下 搜尋旋轉排序陣列 假設有乙個排序的 按未知的旋轉軸旋轉的 陣列 比如,0 1 2 4 5 6 7 可能成為 4 5 6 7 0 1 2 給定乙個目標值進行搜尋,如果在陣列中找到目標值返回陣列中的索引位置,否則返回 1。你可以假設陣列中不存在重複的元素。您在真實的面試中是否遇到過這個題?ye...