以二分搜尋為基本思路
簡要來說:
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的大小關係,確定下次二分查詢...