對於乙個陣列或者是鍊錶,如果想要知道其中是否包含我們需要的target值,可以進行一次線性的查詢,每個元素逐個比對來確定是否包含target,這就是乙個最簡單的查詢演算法。時間複雜度為o(n)
。
假設給定的陣列中的元素是乙個有序的狀態,比如是單調不遞減
或者是單調不遞增
的狀態,對於這種情況可以使用二分查詢來完成。即二分查詢需要滿足兩個條件:
以陣列[0,1,2,3,4,5,6]
為例。我們需要查詢的目標值target是為2,具體的查詢過程如下圖所示:
首先要查詢的區間是【0,6】
,即區間起始位置low=0,區間結束位置high=6。
需要比較區間中間元素和target的大小。中間元素是3,很明顯3大於target說明目標元素在target的左半邊,瞬間將區間縮小一半。如下圖所示。
這時面對的區間是【0,2】
,即low=0,high=2,target = 2。同樣需要比較區間中間的數和target的大小,區間中間的數是1,比target小。說明target在區間的右半部分。區間同樣縮小一半,如下圖所示:
這時區間已經變成了【2,2】
,low=2,high=2,target= 2同樣按照上面的方式計算,找出區間最中間的那個元素,這時中間的元素是2,和目標值target相等,直接返回結果即可。
上面介紹的是target存在陣列中的情況,如果target不存在陣列中是什麼樣的呢?假設target=2.5那麼在區間【2,2】之前的查詢過程都和上面一樣,只有在最後一步時是不一樣的。這時同樣比較區間【2,2】的中間值和target比較,發現target比該值大,那麼就要將low繼續往右移動,這時發現 low>high ,說明該元素不在該陣列中,可以終止查詢了。
def
binary
(nums,target)
: low =
0 high =
len(nums)-1
while low <= high:
mid =
(low + high)//2
if nums[mid]
== target:
return mid
elif nums[mid]
> target:
high = mid -
1else
: low = mid +
1return-1
print
(binary([0
,1,2
,3,4
,5,6
],2)
)print
(binary([0
,1,2
,3,4
,5,6
],2.5)
)
上面的**針對的情況是如果target在陣列中,那麼返回target在陣列中的下標;如果target不在陣列中則返回-1。對於直接返回-1的這種情況其實是對資訊的一種浪費。我們可以返回陣列比元素比target小且最接近於target的那個下標。比如陣列[0,1,2,3,4,5,6]
,target = 2.5,這時返回值就應該是2。
def
binary
(nums,target)
: low =
0 high =
len(nums)-1
while low <= high:
mid =
(low + high)//2
if nums[mid]
== target:
return mid
elif nums[mid]
> target:
high = mid -
1else
: low = mid +
1return high +
1print
(binary([0
,1,2
,3,4
,5,6
],2)
)print
(binary([0
,1,2
,3,4
,5,6
],2.5)
)
def
binary
(nums,target)
: low =
0 high =
len(nums)-1
while low <= high:
mid =
(low + high)//2
if nums[mid]
== target:
return mid
elif nums[mid]
> target:
high = mid -
1else
: low = mid +
1return low-
1print
(binary([0
,1,2
,3,4
,5,6
],2)
)print
(binary([0
,1,2
,3,4
,5,6
],2.5)
)
比如leetcode 354 俄羅斯套娃信封問題中就需要用到返回比該元素小且最接近於該元素的下標
這種二分查詢方式,有興趣的朋友的可以嘗試一下。雖然乙個基礎版本的二分查詢**非常好寫,但是對於二分查詢的變形的問題還是要深入理解二分查詢過程的具體細節,才能在實際中熟練的應用。 查詢演算法 二分查詢
利用二分查詢演算法查詢某乙個元素,前提條件是該被查詢的元素是乙個已經有序的陣列。二分查詢的思想是將陣列元素的最高位 high 和最低位 low 進行標記,取陣列元素的中間 mid 和和要查詢的值 key 進行比較,如果目標值比中間值要大,則將最低位設定為mid 1,繼續進行查詢。如果目標值小於中間值...
查詢演算法 二分查詢
二分查詢的思路是很簡單的,前提是這組資料是有順序的。思路是從中間找乙個數,判斷大小,如果數比中間數大,說明在中間數到結尾的數中,如果小於,則說明在開始和中間數之間,經過多次相同操作,就可以得到我們想查詢的數時間複雜度就是 o logn 非遞迴的實現 const testarr let i 0whil...
查詢演算法 二分查詢
二分查詢是乙個常用的查詢演算法,其原理在於通過不斷切分乙個規則排序,對半的去尋找目標元素所在的區間與位置。但是其有乙個前提,那就是資料結構需要是順序儲存結構,並且關鍵字大小有序排列。例子如下 例 有乙個數列 12,23,45,56,67,89 請使用二分查詢找到56的位置 解 首先mid 0 5 2...