**定义:**二分法是一种在有序数组中查找某一特定元素的算法
算法最坏的时间复杂度为O(logn)
注意:1.数据类型是有范围的,采用L+(R-L)/2更合适
2.注意start=mid+1和end=mid-1,防止死循环
3.数据量不可过大
STL的lower_bound()和upper_bound()
返回小于等于查找元素的下标和返回大于等于查找元素的下标
代码示例:
using namespace std;
#include<iostream>
int binary_search(int a[],int key){
int start=0;
int end=sizeof(a)-1;
while(start<=end){
int mid=start+(end-start)/2;
if(a[mid]<key){
start=mid+1;
}
if(a[mid]>key){
end=mid-1;
}
if(a[mid]==key){
return mid;
}
}
return -1;
}
int main(){
int a[]={1,3,4,5,7,8};
cout<<binary_search(a,4);
}
例1.二分查找lower_bound
有n(1<=n<=1000005)个整数,已经按照从小到大顺序排列好,现在另外给一个整数x,请找出序列中第1个大于x的数的下标!
Input
输入数据包含多个测试实例,每组数据由两行组成,第一行是n和x,第二行是已经有序的n个整数的数列。
Output
对于每个测试实例,请找出序列中第1个小于x的数的位置。
Sample Input
3 3
1 2 4
Sample Output
2
using namespace std;
#include<iostream>
int binary_search(int a[], int key) {
int start = 0;
int end = sizeof(a) ;
while (start < end) {
int mid = start + (end - start) / 2;
if (a[mid] >= key) {
end = mid ;
}
else {
start = mid + 1;
}
}
return start;
}
int main() {
int m;
int n;
int p;
cin >> m >> n;
int a[50] = {0};
for (int i = 0; i < m; i++) {
cin >> p;
a[i] = p;
}
cout << binary_search(a, n);
}
例2:输入n ( n≤100,000)个整数,找出其中的两个数,它们之和等于整数m(假定肯定有解)。题中所有整数都能用int 表示。
方法一:暴力搜
复杂度为O(n*n)
int main() {
int m;
int n;
cin >> n >> m;
for (int i = 0; i <= n; i++) {
for (int k = i + 1; k <= n; k++) {
if (i + k == m) {
cout << i << " " << k << endl;
}
}
}
}
方法二:二分法
复杂度为O(nlogn)
void bin_search(int a[],int n,int p) {
for (int i = 0; i < p; i++) {
for (int start = i,end=p-1; start <=end;) {
int mid = start + (end - start) / 2;
if (a[mid] > n - a[i]) {
end = mid - 1;
}
if (a[mid] < n - a[i]) {
start = mid + 1;
}
if (a[mid] == n - a[i]&&a[mid]!=a[i]) {
cout << a[i] << " " << a[mid] << endl;
break;
}
}
}
}
int main() {
int p;
int n;
cin >> p >> n;//输入p(数的个数),n(总和)
int a[1000];
for (int i = 0; i < p; i++) {
a[i] = i + 1;
}
bin_search(a, n, p);
}
方法三:双指针法
复杂度为O(n)
void bin_search(int m[],int n,int b) {
int start = 0;
int end = b-1;
while (start < end) {
if (m[start] + m[end] < n) {
start++;
}
if (m[start] + m[end] > n) {
end--;
}
if (m[start] + m[end] == n && m[start] != m[end]) {
cout << m[start] << " " << m[end] << endl;
start++;
}
}
}
int main() {
int p;
int n;
cin >> p >> n;//输入p(数的个数),n(总和)
int a[1000];
for (int i = 0; i < p; i++) {
a[i] = i + 1;
}
bin_search(a, n,p);
}