二分查詢,來一道不是那麼複雜的題目

2021-10-06 01:41:14 字數 1777 閱讀 1297

二分查詢的思想和套路已經了然於心了,但是還是有些問題解決不了?這個時候就可能需要多見一些特殊的用例了。這一次再來一種二分查詢的特例。

峰值元素是指其值大於左右相鄰值的元素。

給定乙個輸入陣列 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素並返回其索引。

陣列可能包含多個峰值,在這種情況下,返回任何乙個峰值所在位置即可。

你可以假設 num

s[−1

]=nu

ms[n

+1]=

−∞

nums[-1] = nums[n+1] = -∞

nums[−

1]=n

ums[

n+1]

=−∞。

示例 1:

輸入:nums = [1,2,3,1]

輸出: 2

解釋: 3 是峰值元素,你的函式應該返回其索引 2。

示例 2:

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

輸出: 1 或 5

解釋: 你的函式可以返回索引 1,其峰值元素為 2;

或者返回索引 5, 其峰值元素為 6。

這個問題也是查詢中的乙個典型,雖然看起來不是那麼難,但是告訴你這是乙個二分查詢的題目,想出o(l

gn

)o(lgn)

o(lgn)

複雜度的解也是不那麼容易。

題目中提到後乙個元素不會和前乙個元素相同,這一點就保證了峰值實際上是嚴格的峰值。此外還提到num

s[−1

]=nu

ms[n

+1]=

−∞

nums[-1] = nums[n+1] = -∞

nums[−

1]=n

ums[

n+1]

=−∞,這一條就假設了峰值一定存在。陣列中的最大值一定是峰值。所以問題一定是有解的。而且只需要返回乙個解,肯定不需要遍歷了。

首先注意到這個問題中陣列都不是有序或者區域性有序的,如果要使用二分查詢,這個時候需要聯想二分查詢的特性,如何去劃分子問題。

肯定要找到中間元素,但是中間元素的情況如何決定解的位置。找峰值,仍然以上坡和下坡為例。如果中間元素處於上坡的區間,顯然峰值出現在右邊。如果中間元素處於下坡的區間,則峰值出現在左邊。接下來就是判斷中間元素到底在上坡還是下坡了。那就比較它和自己後面的元素,到底哪個更大。如果比下乙個元素大,就是在下坡,反之則是上坡。(不會出現相等的情況)

找到了如何劃分問題。還需要注意的一點就是,如果自己比下乙個元素大,說明在下坡,此時可能自己就是坡頂元素,這個時候二分法的結束位置就需要包括自己的當前位置。

c++**

int

findpeakelement

(vector<

int>

& nums)

else

}return start;

}

通常的二分查詢,需要對比的是中間元素和兩端元素的關係,但是實際上也可以對比中間元素和周圍元素的關係來查詢。因為計算機中的除法都是向下取整,所以當sta

rt≠e

nd

start \neq end

start

​=en

d時,mid

+1

mid +1

mid+

1一定在區間內,而mid

−1

mid - 1

mid−

1則不一定在。這一點也是需要注意的。

二分查詢時間複雜度的計算

時間複雜度無非就是while迴圈的次數!總共有n個元素,漸漸跟下去就是n,n 2,n 4,n 2 k,其中k就是迴圈的次數 由於你n 2 k取整後 1 即令n 2 k 1 可得k log2n,是以2為底,n的對數 所以時間複雜度可以表示o o logn 二分查詢的時間複雜度是o log n 最壞情況...

二分查詢時間複雜度的計算

時間複雜度無非就是while迴圈的次數!總共有n個元素,漸漸跟下去就是n,n 2,n 4,n 2 k,其中k就是迴圈的次數 由於你n 2 k取整後 1 即令n 2 k 1 可得k log2n,是以2為底,n的對數 所以時間複雜度可以表示o o logn 二分查詢的時間複雜度是o log n 最壞情況...

順序查詢和二分查詢法複雜度的差異

1.問題 寫出兩種檢索演算法 在乙個排好序的陣列t 1 n 中查詢x,如果x在t中,輸出x在 t的下標j 如果x不在t中,輸出j 0。2.分析 兩種檢索演算法,我們選擇1.順序查詢法。2.二分查詢法。3.偽 順序查詢法 for int i 0 i n i 二分查詢法 int top 0,end n ...