81 搜尋旋轉排序陣列 II

2021-10-19 05:11:10 字數 2183 閱讀 1893

題目描述

假設按照公升序排序的陣列在預先未知的某個點上進行了旋轉。

( 例如,陣列[0,0,1,2,2,5,6]可能變為[2,5,6,0,0,1,2])。

編寫乙個函式來判斷給定的目標值是否存在於陣列中。若存在返回true,否則返回false

示例 1:

輸入: nums = [2,5,6,0,0,1,2], target = 0

輸出: true

示例 2:

輸入: nums = [2,5,6,0,0,1,2], target = 3

輸出: false

高階:題解:參考 搜尋旋轉排序陣列 一題,這題增加了乙個條件:可以有重複值,這個條件有點麻煩。。。

還是用二分來搞定。

注意:二分不一定必須要有單調性,二分的本質是尋找某種性質的分界點。只要找到某種性質,可以確定目標在區間的前半部分還是後半部分,就可以用二分找到這個分界點。

為了便於分析,將陣列中的元素畫在二維座標系中,橫軸代表下標,縱軸代表值。

水平的實線表示相同的元素。可以發現,除了黑色水平那段,其餘部分均滿足二分性質:豎直的虛線左邊的元素均滿足arr

[i]>=a

rr[0

]arr[i]>=arr[0]

arr[i]

>=a

rr[0

],而虛線右邊(除了黑色部分)元素均滿足arr[i]

r[0]

arr[i]ar

r[i]

r[0]

。首先,我們需要把黑色的水平段刪除,至於為什麼刪除呢?考慮一種情況:arr

[mid

]==a

[0]arr[mid] == a[0]

arr[mi

d]==

a[0]

,這種情況下,根本不知道往哪邊走,所以只能刪除。

還需要處理陣列未旋轉的情況,當刪除黑色水平段後,若剩下的最後乙個元素大於等於arr[0],說明陣列完全單調。

最壞情況:元素均相等情況下的時間複雜度為o(n

)o(n)

o(n)

。法一:兩次二分。參考 在有序旋轉陣列中找到最小值 一題,如果我們可以找到分界點,就可以確定target在左右哪個區間,然後直接在該區間上進行二分查詢即可。

把複雜問題分解成簡單的子問題思想很重要。

class
solution

int l =

0, r = n, m;

if( nums[0]

> nums[n])if

( target <= nums[n]

) r = n;

else l =0,

--r;

}while

( l < r )

return nums[r]

== target;}}

;/*記憶體:13.6mb,擊敗:29.95%

*/法二:

在二分過程中,通過一些條件判斷target在哪個區間也行:

class

solution

int l =

0, r = n, m;

while

( l < r )

else

}return nums[r]

== target;}}

;/*記憶體:13.6mb,擊敗:30.23%

*/

法三:

直接掃瞄一遍nums。。。

class

solution};

/*記憶體:13.6mb,擊敗:22.29%

*/

三種方法記憶體消耗簡直離譜。。。

81 搜尋旋轉排序陣列 II

假設按照公升序排序的陣列在預先未知的某個點上進行了旋轉。例如,陣列 0,0,1,2,2,5,6 可能變為 2,5,6,0,0,1,2 編寫乙個函式來判斷給定的目標值是否存在於陣列中。若存在返回 true,否則返回 false。示例 1 輸入 nums 2,5,6,0,0,1,2 target 0 輸...

81 搜尋旋轉排序陣列 II

假設按照公升序排序的陣列在預先未知的某個點上進行了旋轉。例如,陣列 0,0,1,2,2,5,6 可能變為 2,5,6,0,0,1,2 編寫乙個函式來判斷給定的目標值是否存在於陣列中。若存在返回 true,否則返回 false。示例 1 輸入 nums 2,5,6,0,0,1,2 target 0 輸...

81 搜尋旋轉排序陣列 II

題目.middle 這是乙個二分查詢的公升級版,我們可以認為,經過旋轉後分成了兩部分,left half和right half,所以每次根據mid所在的位置,淘汰掉一半的資料。千萬不要去尋找旋轉點。這樣會搞得很麻煩 package main import fmt func search nums i...