二分搜法,是通過不斷縮小解可能存在的範圍,從而求得問題最優解的方法。
舉個例子:
從有序陣列中查詢某個值:
lower_bound
給定長度是n的單調不下降序列,a[0],a[1],a[2],...........a[n-1],和乙個數k,求滿足a[i]>=k條件的最小的i。不存在的情況下輸出n.
限制條件:
1<=n<=10^6
0<=k<=10^9
0<=a[0]<=a[1]<=.....a[n-1]<=10^9
輸入:n=5
a=k=3
輸出:1(a[0]<3,a[1]>=3)
2 3 3 5 6
a[2]=3和3進行比較,可以知道解不大於2。
2 3 35 6
a[1]=3和3進行比較,可以知道解不大於1。
2 3 3 5 6
a[0]=2和3進行比較,可以知道解大於0。
23 3 5 6
解的變化範圍
演算法描述:
int n,k;
int a[max_n];
void solve()
else
}//這時,low+1=high
printf("%d\n",high);
}這種演算法就是二分搜法。
此外stl以lower_bound函式的形式實現了二分搜。這個演算法處理在有序陣列中查詢值之外,在求最優解的問題上也非常有用。
讓我們考慮一下「求滿足某個條件c(x)的最小的x」這乙個問題。對於任意滿足c(x)的x,如果所有的x'>=x也滿足c(x')的話,我們就可一使用二分搜來求得最小的x。
首先我們將區間的左端點初始化為不滿足c(x)的值,右端點初始化為滿足c(x)的值。然後每次去終點,mid=(low+high)/2,判斷c(mid)是否滿足並縮小範圍,
直到(low,high]足夠小了為止。最後high就是要求得最小值。求最大值用同樣的方法。
二分搜尋的階數判定:
在輸出小數的問題中,一般都會指定允許的誤差範圍,或者是指定輸出中小數點後面的位數。因此在使用二分搜尋時有必要設定合理的結束條件來滿足精度的要求。
可以用迴圈次數最為終止條件。一次迴圈將範圍縮小一半,迴圈100次則可以達到10的負30 次冪的精度範圍,基本上是沒有問題的。除此之外,也可以將終止條件設定為像
(high-low)>eps這樣,指定乙個區間的大小。在這種情況下,如果eps取得太小了,就有可能因為浮點小數精度的原因導致陷入死迴圈,千萬小心。
二分搜尋總結
看了這篇帖子,對思路很簡單,細節是魔鬼感同身受,故自己來做個總結。在乙個一維有序陣列 nums 中查詢 target 是否存在,存在返回 index 不存在返回 1 public int binarysearch int nums,int target else if nums mid target...
幾種二分搜尋總結
1.如果有重複,找的是最左邊 leftmost 的那個的index。如果不存在,返回的是應該插入的index,這裡陣列長度是可變的。見乙個easy題 35題 class solution else return lo 2.如果存在,返回index 如果有重複的,因為它找到重複中的任何乙個就retur...
總結 二分查詢(下)
總結 二分查詢 下 一 四種常見的二分查詢變形問題 16 二分查詢 下 如何快速定位ip對應的省份位址?file j geektime 唯一更新qq群170701297 ebook 資料結構與演算法之美 16二分查詢 下 如何快速定位ip對應的省份位址?html 2019 2 17 17 27 19...