二分法是一種對於有序數列查找時間複雜度爲O(logN)的方法。
常見二分法
最常用的方法是找出該數列中是否含有某一個數字,有則返回其位索引,沒有則退出返回-1。
while(l<=r){
mid = (l+r)/2;
if(arr[mid]==target){
return mid;
}
if (arr[mid]<target){
l = mid + 1;// 由於除法是向下取整l=mid+1;不然在特定情況下會陷入l=mid的循環
}
else{
r = mid - 1;// r = mid; 是可以的因爲只有l=r時纔有可能循環
}
}
return -1;
NOTE 1: 如果行1 (l <= r) 改爲 (l<r)則會漏掉當l=r且滿足條件的情況
二分法找數字的第一個索引位或最後一個索引位
不要在找到時停止,直到遍歷到第一個索引位或最後一個索引位,同時如果不存在該數字,則返回不大於該數字的最大元素的索引
int realtwosplit(vector<int> arr, int target, int l_flag) {
int n = arr.size();
int mid, l = 0, r = n - 1;
// find the last one which is not bigger than target; l_flag = 1;
while (l < r) {
mid = (l + r) / 2;
if (arr[mid] >target||l_flag && arr[mid]== target) {
r = mid;//+1;
}
else {
l = mid + 1;
}
}
if (l_flag) {
if (arr[l] <= target) return l;
else return l - 1;
}
else {
if (arr[l] < target && arr[l+1]>target) return l;
else if (arr[l] < target && arr[l + 1] <= target) return l + 1;
else return l - 1;
}
return l;
}
NOTE 2:l_flag作爲控制第一索引位的flag