二分查詢是一種很有效率的查詢方式,每次查詢後餘下的區間是指數級遞減的。
二分查詢的限制也很明顯,就是資料必須是拍過序的。
首先我們來看通過二分查詢的方式來計算乙個數的平方根
def mysqrt(n: int, left: int, right: int, bit_num: float):
mid = left + (right - left)/2
if abs(n - mid * mid) <= math.pow(0.1, bit_num):
return mid
if n - mid * mid > 0:
return mysqrt(n, mid, right, bit_num)
else:
return mysqrt(n, left, mid, bit_num)
可以看出來**非常少,也很容易理解,每次都取中值的平方,判斷中值的平方與n的差值,如果比n大,就在left到中值的區域,否則就在另外一邊。
下面看二分查詢的一些變形:
# 4 5 6 1 2 3
# 5 6 1 2 3 4
# 3 4 5 6 1 2
#查詢迴圈有序陣列的分割點
def find_pos(seracharr: , left: int, right: int):
if seracharr[left] < seracharr[right]:
return left
mid = left + (right-left)/2
if seracharr[mid] > seracharr[left]:
return find_pos(seracharr, mid + 1, right)
else:
return find_pos(seracharr, left, mid - 1)
#二分查詢第乙個相等的索引
def binary_find_first_same(searcharr: , left: int,right: int, value: int):
if left > right:
return -1
mid = left + (right-left)//2
if searcharr[mid] > value:
return binary_find_first_same(searcharr, left, mid -1, value)
elif searcharr[mid] < value:
return binary_find_first_same(searcharr, mid+1, right, value)
else:
if mid == 0 or searcharr[mid-1] != value:
return mid
else:
return binary_find_first_same(searcharr, left, mid -1, value)
#二分查詢最後乙個相等的索引
def binary_find_last_same(searcharr: , left: int,right: int, value: int):
if left > right:
return -1
mid = left + (right-left)//2
if searcharr[mid] > value:
return binary_find_last_same(searcharr, left, mid -1, value)
elif searcharr[mid] < value:
return binary_find_last_same(searcharr, mid+1, right, value)
else:
if mid == right or searcharr[mid+1] != value:
return mid
else:
return binary_find_last_same(searcharr, mid+1, right, value)
#二分查詢第乙個大於指定值的索引
def binary_find_first_big(searcharr: , left: int, right: int, value: int):
if left > right:
return -1
mid = left + (right-left)//2
if searcharr[mid] > value:
if mid == 0 or searcharr[mid-1] <= value:
return mid
else:
return binary_find_first_big(searcharr, left, mid -1, value)
else:
return binary_find_first_big(searcharr, mid+1, right, value)
#二分查詢第乙個小於指定值的索引
def binary_find_first_less(searcharr: , left: int, right: int, value: int):
if left > right:
return -1
mid = left + (right - left) // 2
if searcharr[mid] >= value:
return binary_find_first_less(searcharr, left, mid - 1, value)
else:
if mid == right or searcharr[mid+1] >= value:
return mid
else:
return binary_find_first_less(searcharr, mid + 1, right, value)
二分查詢的應用
最大的最小值,最小的最大值用二分 這個發現緣起於兩段看似相同的 這兩段 看似相同,實則大有學問 我編了乙個簡單的題目 在1,2,3,三個數中找到大於等於2的最小值 這是乙個求最小的最大值的問題,按道理來我們要用左開右閉的區間 及靠上方的 去逼近答案 若用靠下方的 左閉右開的區間 則步驟如下 1 l ...
二分查詢的變形應用
演算法理解 獲取陣列中第乙個空閒的塊 比如array 為1111111 111000000 0 問題就變成 尋找array 中第乙個出現的0 演算法一 遍歷陣列找到第乙個 0 o n 演算法二 二分查詢 二分查詢成功條件 array i t 失敗條件 l u 對於本問題來說,成功條件則是 array...
迭代二分查詢二分查詢
在寫這篇文章之前,已經寫過了幾篇關於改迭代二分查詢主題的文章,想要了解的朋友可以去翻一下之前的文章 bentley在他的著作 writing correct programs 中寫道,90 的計算機專家不能在2小時內寫出完整確正的二分搜尋演算法。難怪有人說,二分查詢道理單簡,甚至小學生都能明確。不過...