二分搜尋 旋轉陣列

2021-09-29 12:09:20 字數 1340 閱讀 2075

以二分搜尋為基本思路

簡要來說:

nums[0] <= nums[mid](0 - mid不包含旋轉)且nums[0] <= target <= nums[mid] 時 high 向前規約;

nums[mid] < nums[0](0 - mid包含旋轉),target <= nums[mid] < nums[0] 時向前規約(target 在旋轉位置到 mid 之間)

nums[mid] < nums[0],nums[mid] < nums[0] <= target 時向前規約(target 在 0 到旋轉位置之間)

其他情況向後規約

也就是說nums[mid] < nums[0],nums[0] > target,target > nums[mid] 三項均為真或者只有一項為真時向後規約。

原文的分析是:

注意到原陣列為有限制的有序陣列(除了在某個點會突然下降外均為公升序陣列)

if nums[0] <= nums[i] 那麼 nums[0] 到 nums[i] 為有序陣列,那麼當 nums[0] <= target <= nums[i] 時我們應該在 0-i0−i 範圍內查詢;

if nums[i] < nums[0] 那麼在 0-i0−i 區間的某個點處發生了下降(旋轉),那麼 i+1i+1 到最後乙個數字的區間為有序陣列,並且所有的數字都是小於 nums[0] 且大於 nums[i],當target不屬於 nums[0] 到 nums[i] 時(target <= nums[i] < nums[0] or nums[i] < nums[0] <= target),我們應該在 0-i0−i 區間內查詢。

上述三種情況可以總結如下:

nums[0] <= target <= nums[i]

target <= nums[i] < nums[0]

nums[i] < nums[0] <= target

所以我們進行三項判斷:

(nums[0] <= target), (target <= nums[i]) ,(nums[i] < nums[0]),現在我們想知道這三項中有哪兩項為真(明顯這三項不可能均為真或均為假(因為這三項可能已經包含了所有情況))

所以我們現在只需要區別出這三項中有兩項為真還是只有一項為真。

使用 「異或」 操作可以輕鬆的得到上述結果(兩項為真時異或結果為假,一項為真時異或結果為真,可以畫真值表進行驗證)

之後我們通過二分查詢不斷做小 target 可能位於的區間直到 low==high,此時如果 nums[low]==target 則找到了,

class solution

return lo == hi && nums[lo] == target ? lo : -1;}};

二分搜尋應用(旋轉陣列) C語言

出處 劍指offer 題目 把乙個陣列最開始的若干個元素搬到陣列的末尾,稱之為陣列的旋轉。輸入乙個遞增排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1。1.用遍歷陣列的方法來實現 int mininorder int num,index1,index2 inde...

旋轉陣列的二分查詢

1 什麼是旋轉陣列 旋轉陣列是將乙個有序陣列的前若干個數旋轉到陣列末尾,例如陣列a 5 那麼陣列b 5 為陣列a的乙個旋轉陣列 2 旋轉陣列的二分查詢之找到給定key 對於給定乙個數key,如何從旋轉陣列中找到key的位置呢?由於旋轉陣列部分有序,故可以利用二分查詢思想來設計演算法,從而達到logn...

旋轉陣列的二分查詢

1.問題描述 已知有序陣列a n 從中間某個位置k k未知,k 1表示整個陣列有序 分開,然後將前後兩部分互換,得到新的陣列,在該新陣列的查詢元素x。如 a 從k 4分開,得到新陣列a 一次二分查詢 二分查詢演算法有兩個關鍵點 1 陣列有序 2 根據當前區間的中間元素與x的大小關係,確定下次二分查詢...