關於幾種二分的想法

2021-06-27 12:49:39 字數 2053 閱讀 1821

一般的二分能解決在單調序列中查詢某個數是否存在的作用,假如查詢的某數有多個,我要你輸出第乙個的位置,或者最後乙個的位置,其實這些問題也能用而二分解決。

c++中貌似自帶lower_bound 和upper_bound函式,分別是在單調有序的序列中,找到第乙個大於給定值和第乙個大於等於給定值的數的位置,但是這些都是怎麼實現的呢?

現在有一串單調非遞減的序列(意味著有重複數字),那麼先說明4個問題:

1 找出這個序列第乙個大於給定數字k的位置和那個數,這個數可能出現了好幾次,我要找第一次的位置;

2 找出這個序列第乙個大於等於給定數字k的位置和那個數,這個數可能出現了好幾次,我要找第一次的位置;

3 找出這個序列第乙個大於給定數字k的位置和那個數,這個數可能出現了好幾次,我要找最後一次的位置;

4 找出這個序列第乙個大於等於給定數字k的位置和那個數,這個數可能出現了好幾次,我要找最後一次的位置;

3,4兩個問題可能表述的不夠清楚,這裡的意思是,假如這串數中從小到大第乙個滿足條件的數有好多個,或者說出現了很多次,我要求的是第乙個符合條件的最後一次出現的,並不是整串中的最後乙個,比如1,2,2,2,3 ,我要找最後乙個(第一次)大於等於2的位置,我要求的不是3這個位置,而是最後乙個2的位置。

對於問題1,有如下**:

while(lk)

r=mid;

else if(a[mid]<=k)

l=mid+1;

}

對於問題2,有如下**:

while(l=k)

r=mid;

else if(a[mid]

最後跳出迴圈時l=r就是所求的位置。

兩者的差距就是取到等號的時候執行的不同的語句,一般來說二分最怕的是死迴圈,我認為可以從邊界考慮,比如從l+1==r,l+2==r,l+3==r這三種情況,會發現這三種情況的任意一種都不會導致死迴圈,而且第三章情況會變成第一種情況,並且退出迴圈時,l==r。

那對於問題3和問題4,我們不能直接解決它,但是可以通過二分找兩次來解決,

對於問題3,我們先找到第乙個大於k的數的位置,設為pos,然後我們再找第乙個大於a[pos]這個數的位置,

設為pos2,然後pos2-1就是答案了。

對於問題4,我們先找到第乙個大於等於k的數的位置,設為pos3,然後在找第乙個大於a[pos3]這個數的位置,

設為pos4,然後pos4-1就是答案了。

其實還有4個類似的問題,現在要找出最後乙個出現小於(等於)k的數的第乙個位置和最後乙個位置。

也可以用差不多的方法解決。

接著來考慮問題5到問題8,

問題5找出這個序列最後乙個小於給定數字k的位置和那個數,這個數可能出現了好幾次,我要找最後一次的位置;

問題6找出這個序列最後乙個小於等於給定數字k的位置和那個數,這個數可能出現了好幾次,我要找最後一次的位置;

問題7找出這個序列最後乙個小於給定數字k的位置和那個數,這個數可能出現了好幾次,我要找第一次的位置;

問題8找出這個序列最後乙個小於等於給定數字k的位置和那個數,這個數可能出現了好幾次,我要找第一次的位置;

問題5和問題6,其實蠻簡單的,只需要將問題2和問題1的位置減去1即可。

即問題2答案-1=問題5答案,問題1答案-1=問題6答案。

對於問題7,可以先找到第乙個大於等於k這個數的位置,記為pos5,

然後我再找第乙個大於等於a[pos5-1]的位置pos6即為答案。

對於問題8,可以先找到第乙個大於k這個數的位置,記為pos7,

然後我再找第乙個大於等於a[pos7-1]的位置pos8即為答案。

至此所有問題都解決,二分真是乙個給力的東西!

最後還需要說明的一點,我這種二分的寫法沒辦法處理一直特殊情況 ,為了方便理解,之前也沒有說明,我**中的l和r一直代表所能取到的數的閉區間,但是會有有可能,我要找的數它一開始就不在這個區間,比如1,2,3,4,5,我要找第乙個大於6的數的位置,我初始化l=0,r=4那麼無論如何這個求解結果都是錯的,因為根本不存在0到4的範圍裡有這個數。我想到的一種做法就是,初始化r=5,那麼答案是正確的。r初始化的位置本來選取最後乙個數的位置,但是為了保證結果的準確,可以初始化為最後乙個數的位置+1。

poj 3104 二分想法

給你n個數表示含水量,給你乙個k表示每分鐘洗衣機能脫水k滴 每分鐘沒有在洗衣機的衣服自動脫水一滴,求把全部水託幹最小時間,怎麼都沒想到居然是二分 好吧,二分列舉最小時間mid,然後求實際所需時間再 經行判斷,如果列舉時間為mid,對每件衣服num i 如果num i 小於mid 很顯然直接自然幹最好...

二分入門 二分知識 及 幾種情況

二分排序 時間複雜度是 log n 最壞的情況下是 n 乙個條件是帶查詢陣列是有序的,分兩種 一公升序 而降序 主要思路就是指定兩個指標start end 分別指向陣列元素的兩端,然後比較陣列中間的arrat mid 和待查詢元素,n 直接找到某值在右若干個 n時 找n 以下是 若找到中間值是n則輸...

二分的幾種方法

64種。對其進行分類 向下取整 向上取整 共2種 閉區間 左閉右開區間 左開右閉區間 開區間 共4種 對於不下降序列a,求最小的i,使得a i key 對於不下降序列a,求最大的i,使得a i key 對於不下降序列a,求最小的i,使得a i key 對於不下降序列a,求最大的i,使得a i key...