半有序陣列的最值查詢(二分法)

2021-10-22 14:27:03 字數 1803 閱讀 7198

劍指offer 11

題目描述:

陣列的旋轉,就是把乙個陣列開始的若干個元素搬到陣列的末尾。輸入乙個有序陣列的旋轉陣列,求出其最小值的高效演算法。

示例1:輸入:[3,4,5,1,2] 輸出:1

示例2:輸入:[2,2,2,0,1] 輸出:0

示例3 : 輸入:[1,1,1,0,1] 輸出:0

思路

其中橫軸表示陣列元素的下標,縱軸表示陣列元素的值。圖中標出了最小值的位置,是我們需要旋轉的目標。

我們考慮陣列中的最後乙個元素 x:在最小值右側的元素,它們的值一定都小於等於 x;而在最小值左側的元素,它們的值一定都大於等於 x。因此,我們可以根據這一條性質,通過二分查詢的方法找出最小值。

在二分查詢的每一步中,左邊界為low,右邊界為high,區間的中點為 mid,最小值就在該區間內。我們將中軸元素 num[mid]與右邊界元素 num[high] 進行比較,可能會有以下的三種情況:

第一種情況是num[mid] < num[high]。如下圖所示,這說明 中間節點mid 是最小值右側的元素,因此我們可以忽略二分查詢區間的右半部分。

第二種情況是num[mid] > num[high]。如下圖所示,這說明 中間節點mid 是最小值左側的元素,因此我們可以忽略二分查詢區間的左半部分。

第三種情況是num[mid] = num[high]。如下圖所示,由於重複元素的存在,我們並不能確定 mid究竟在最小值的左側還是右側,因此我們不能莽撞地忽略某一部分的元素。我們唯一可以知道的是,由於它們的值相同,所以無論 num[high] 是不是最小值,都有乙個它的「替代品」num[mid],因此我們可以忽略二分查詢區間的右端點。

//若中間節點大於最後乙個值,則mid位於min左側

else if(numbers[mid] > numbers[high])

//若等於,則不確定最小值在哪側,所以只能將high減1,向前移一位

else

}return numbers[low];

}}重新賦值時加1 或 不加1 或 減1的問題()

//2.但對於比較時相等的情況

力扣 852

題目描述:

符合下列屬性的陣列 arr 稱為 山脈陣列 :

arr.length >= 3

存在 i(0 < i < arr.length - 1)使得:

arr[0] < arr[1] < … arr[i-1] < arr[i]

arr[i] > arr[i+1] > … > arr[arr.length - 1]

返回轉折點arr[i]的下標i。

思路:

這是個山脈陣列,也就是」凸陣列「,前半段是上公升的,後半段是下降的;故可以通過比較相鄰兩個元素(索引為mid和mid+1)的大小來確定mid屬於哪個階段,進而判斷max在mid的哪側。

class solution 

//題目中沒有等於的情況

二分法查詢有序陣列

package array public class testbinarysearch 指定查詢的元素 int num 12 用二分法查詢,返回索引 int start 0 int end arr.length 1 end的設定應該為陣列最後一位 int index 1 用於標誌是否查詢到指定元素 ...

查詢有序陣列元素 二分法

查詢的方法多種多樣,今天提到的就是對於乙個有序陣列而言最方便最高效率的方法 二分法,也叫折半查詢。具體 如下 二分法,也叫折半查詢 include include intb search int a,int left,int right,int k else if a mid k else retu...

有序陣列中二分法查詢

二分法查詢適用於資料量較大時,但是資料需要先排好順序。首先,從陣列的中間元素開始搜尋,如果該元素正好是目標元素,則搜尋過程結束,否則執行下一步。如果目標元素大於 小於中間元素,則在陣列大於 小於中間元素的那一半區域查詢,然後重複步驟1的操作。如果某一步陣列為空,則表示找不到目標元素。時間複雜度為 o...