二分法
自我理解
查找目标target时,使用区间[left,right];此时的left=middle+1,right=middle-1,return middle;
查找左右边界时,使用区间[left,right);此时返回时left=right,返回之后需要检查left和right的位置上的元素,若是查找边界,则无须检查。
本质
「二分」不是单纯指从有序数组中快速找某个数,这只是「二分」的一个应用。
「二分」的本质是二段性,并非单调性。只要一段满足某个性质,另外一段不满足某个性质,就可以用「二分」
自己写二分法详解
STL内置的二分查找算法
binary_search
//stl的内置二分查找的算法其搜索空间为[left,right)
//返回值为bool型
return binary_search(nums.begin()+left,nums.begin()+right,target);
lower_bound(只可以用于升序)
//lower_bound的返回值是跟查找元素一样大,或者比查找元素大的第一个元素的下标
//(等于优先,如果没有等于就是第一个大于);
//这里的下标在每个容器里都是不一样的,在数组里面是数组下标,在STL容器中是迭代器指针;
//所以要知道准确位置还要减去数组原来的下标,或者迭代器的begin()指针
int a[] = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4};
cout << (lower_bound(a, a + 12, 4) - a) << endl; //输出 9
cout << (lower_bound(a, a + 12, 1) - a) << endl; //输出 0
cout << (lower_bound(a, a + 12, 3) - a) << endl; //输出 6
cout << (lower_bound(a, a + 12, 5) - a) << endl; //输出 12
cout << (lower_bound(a, a + 12, 0) - a) << endl; //输出 0
upper_bound(只可以用于升序)
//upper_bound跟lower_bound不同的是返回值是比查找元素大的第一个元素的下标
int a[] = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4};
cout << (upper_bound(a, a + 12, 4) - a) << endl; //输出 12
cout << (upper_bound(a, a + 12, 1) - a) << endl; //输出 3
cout << (upper_bound(a, a + 12, 3) - a) << endl; //输出 9
cout << (upper_bound(a, a + 12, 5) - a) << endl; //输出 12
cout << (upper_bound(a, a + 12, 0) - a) << endl; //输出 0