雖然二分法很簡單,但是之前並沒有對其有過太多的注意,只是把它當成乙個查詢元素的方法來應用,但是隨著後面做題的深入,發現二分法也有很多講究,所以這裡做乙個總結歸納一下;
一、二分法的基礎概念:
二分法研究的序列可以分為重複或者非重複序列,其序列要求都是遞增有序的;
對於非重複序列,我們可以很簡單的給出相應的推理和邏輯;
例如,我們如果要在乙個嚴格遞增序列中查詢給定的x,就可以有以下**:
int binarysearch(int a,int left,int right,int x)else
}return -1;
}
注意兩點:
1.判定條件left<=right,有的情況下寫成left這樣就可以很好的避免溢位,從而保證能夠進行mid的計算;
上述針對的是遞增非重複序列,如果重複序列,我們又該作何思考?
例如示例中給出的問題,如果給出乙個重複的遞增序列a,我們需要求出第乙個大於等於x的位置l以及第乙個大於x的元素的位置r;
這是兩個小問題,首先先進行第乙個小問題的求解:找出第乙個大於等於x的位置l;
其實對於這個問題,前提就已經預設了,必有l存在,所以判定條件就會發生相應的變化;
int lower_bound(int a,int left,int right,int x)else
}return left;
}
這裡我們可以看出變了兩個條件,第乙個是left=x;
對於第乙個條件的改變,我們可以理解為把符合條件的元素夾出來,當迴圈終止的時候,必有left=right,此時兩個索引指向同乙個元素,該元素就是我們在尋找的元素;
而對於第二個條件的改變,則是由於題目性質決定的;如果中間點大於等於x,則我們可以認為要尋找的第乙個x在mid的左邊,所以right=mid。即使在等於條件下,由於right=mid,所以還是可以保證要尋找的數在[left,right]區間內;這一點和之前的mid+1和mid-1完全不同,其根本原因是序列內元素是否唯一;
如果難以判別使用哪種方法,則每次及逆行mid迭代的時候,一定要試一試邊界是否能夠像預期那樣包括進行需要尋找的元素;
第二個自問題就是求序列中第乙個大於x的位置;
對於這個問題,我們仍然需要關注的是判定條件;
**如下:
int upper_bound(int a,int left,int right,int x)else
}return left;
}
對於個演算法,同樣的我們需要left==right來將符合的值夾出來;
當a[mid]>x時,由於我們尋找的時大於x的值,此時該值必在mid的左邊,同樣的,如果mid就是大於x的值,也應該包括進去,所以此時,right=mid;
當a[mid]<=x時,由於我們尋找的是乙個大於x的值,所以mid不必包括進去,left=mid+1;
總的來說,上述推舉的方法,都在解決乙個核心問題:在該序列中,找到第乙個符合該條件的值;
二、二分法的主要應用:
1.利用二分法求某數字的近似值:
這個問題其實很經典,自己以前碰到過幾次;
例如:求解根號2的近似值,要求精度在10^-5;
這個問題就可以利用該方法進行計算;
首先我們需要構建目標函式f(x)=x^2,從而轉換成1~2區間內的實數計算;
設定邊界left=1,right=2,來利用函式進行逼近;
**如下:
const double eps=1e-5;
double f(double x)
int binarysearch()else
}return mid;
}
2.快速冪:
快速冪就是給出三個整數a,b,m,求得a^b%m;
這個問題也可以採用二分思想來進行遞迴計算;
若b是奇數:a^b=a*a^(b-1)
若b是偶數:a^b=a^(b/2)*a^(b/2);
**如下:
long long binarypow(long long a,long long b,long long m)
}
注意上述的mul,不要單純計算兩次a^(b/2),而使用mul,這樣可以適當的介紹時間複雜度; 關於二分法問題個人理解
雖然二分法很簡單,但是之前並沒有對其有過太多的注意,只是把它當成乙個查詢元素的方法來應用,但是隨著後面做題的深入,發現二分法也有很多講究,所以這裡做乙個總結歸納一下 一 二分法的基礎概念 二分法研究的序列可以分為重複或者非重複序列,其序列要求都是遞增有序的 對於非重複序列,我們可以很簡單的給出相應的...
關於二分法查詢
今天在 c primer 第五版page101上看見乙個問題 在二分法搜尋中為什麼用的是 mid beg end beg 2 而非 mid beg end 2 從我原先的思維,去兩個數的中間值確實是兩數相加除以二,所以想了好一會兒也沒想明白,無奈之下只好求助google了 1.beg end有溢位風...
關於二分法查詢
與一般的查詢方式相比二分法查詢則顯得高效快速,即只要較少的查詢次數就可以完成快速地搜尋。在進行二分法查詢前需要先對資料進行排序,定義left,right兩個變數,然後在這組資料中找到mid right left right 2,然後將待查詢元素與mid所指元素進行比較,如果相等則返回,如果查詢元素大...