LeetCode 旋轉排序陣列問題總結

2021-10-08 11:13:39 字數 2515 閱讀 5093

前言

​ 所謂旋轉排序陣列,就是指按照公升序排序的陣列在預先未知的某個點上進行了旋轉(例如,陣列[0,1,2,4,5,6,7]可能變為[4,5,6,7,0,1,2])。而leetcode上與此相關的的題共有三道,下面就具體來分析一下這三題。

搜尋旋轉排序陣列(leetcode 33題)

搜尋乙個給定的目標值,如果陣列中存在這個目標值,則返回它的索引,否則返回 -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),則可知最終必須使用二分法。然後再具體分析旋轉陣列的特徵,假設在下標i處進行了旋轉,旋轉後的序列為i ~ n-1, 0 ~ i-1,由於陣列本身是公升序排列的,所以仔細分析mid中間結點的位置,便可以找到這題的突破口,假設mid處於i ~ n-1區間內,那麼i ~ mid段就是有序的,相對地,mid ~ i-1就是無序的。當mid結點處於0 ~ i-1區間時,易知mid ~ i-1段是有序的,相對地,i ~ mid就是無序的。可以發現,無論mid在哪個位置,總能得到乙個有序段,最終我們也就是利用有序段,來每次排除一半的資料。

​ 為了分析有序段,再看題目,因為陣列為公升序,因此我們每次只需要和最右邊的結點進行比較即可。若nums[mid] < nums[right],則mid ~ right段為有序,若nums[mid] > nums[right],由於陣列整體為公升序,原陣列中左邊的資料一定是小於右邊的,因此在mid ~ right存在乙個旋轉點,即該段是無序的,再由上文分析可知,無論mid處於哪一段,總存在有序區間,因此此時i ~ mid段是有序的。

​ 當我們得到有序段後,我們便可以根據target是否存在於有序段來取捨一半的資料,最終的**如下:

public

intsearch

(int

nums,

int target)

if(nums[mid]

> nums[right]

)else

}else

else}}

return-1

;}

複雜度分析

尋找旋轉排序陣列中的最小值(leetcode153題)

分析​ 本題的條件和上一題相同,取別是上題要求找到乙個目標值,而本題則要求找到最小值。再次回想之前的分析,假設在下標i處進行了旋轉,旋轉後的序列為i ~ n-1, 0 ~ i-1,對於mid結點而言,由之前的分析可知,可以由mid結點與最右邊的結點的值的大小關係,判斷出有序區間處於mid之前還是之後。再次分析有序區間,假設i ~ mid段為有序,那麼陣列一定是在mid ~ i-1段的某個位置進行了旋轉,相應地,最小值也存在於這個區間,即存在於無序段。當mid ~ i-1為有序時,則根據上文的分析,最小值也一定存在於存在旋轉結點的區間,即無序段。

​ 經過上文的分析,可知最小值(也就是旋轉結點)一定存在於無序段,因此**也很容易得出,如下:

public

intfindmin

(int

nums)

else

}return nums[left]

;}

複雜度分析

存在重複值的陣列

​ 以上兩題均是不考慮陣列有重複元素的情況,而leetcode81題和154題,則正是以上兩題存在重複元素的改變。當存在重複元素時,我們在判斷midright結點的大小也將多了一種可能相等的情況,那麼怎麼考慮相等呢?其實我們只要每次在相等情況判斷時,都只將right--即可,因為不管是尋找目標值target,還是尋找陣列最小值,因為midright相等,所以每次去掉最右結點,再對剩下部分之前的判斷,即可得到最終的結果。但是,在有重複值的情況下,演算法的時間複雜度也有了改變,在最好的情況下(陣列中不存在重複元素),仍未o(logn)。但在最壞的情況下(陣列元素全部相等),由於每次只能將陣列大小縮減1,因此將退化為o(n)。

Leetcode 搜尋旋轉排序陣列

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

leetcode 搜尋旋轉排序陣列

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

LeetCode 搜尋旋轉排序陣列

原題鏈結 33.搜尋旋轉排序陣列 給你乙個整數陣列 nums 和乙個整數 target 該整數陣列原本是按公升序排列,但輸入時在預先未知的某個點上進行了旋轉。例如,陣列 0,1,2,4,5,6,7 可能變為 4,5,6,7,0,1,2 請你在陣列中搜尋 target 如果陣列中存在這個目標值,則返回...