STL库函数
// 常规写法
int targe;
vector<int> v;
int pos1 = lower_bound(v.begin(), v.end(), targe) - v.begin(); // 大于等于
int pos2 = upper_bound(v.begin(), v.end(), targe) - v.begin(); // 大于
// 自定义结构体写法
struct node{
int a, b;
// 重写判断函数即可
friend operator<(node x, node y) {
return x.b > y.b;
}
};
vector<node> a;
sort(a.begin(), a.end());
node tmp;
int pos3 = lower_bound(a.begin(), a.end(), tmp) - a.begin();
int pos4 = upper_bound(a.begin(), a.end(), tmp) - a.begin();
// 改逻辑,降序
int pos5 = lower_bound(v.begin(), v.end(), targe ,greater<int>()) - v.begin(); // 小于等于
int pos6 = upper_bound(v.begin(), v.end(), targe ,greater<int>()) - v.begin(); // 小于
手写二分
升序
vector<int> a;
int l = 0, r = a.size()-1;
int targe, id = a.size();
while (l <= r) {
int mid = l+r>>1;
if (a[mid] < targe) // 大于等于targe的数,大于则改为 a[mid] <= targe
l = mid+1;
else {
id = min(id, mid);
r = mid-1;
}
}
降序
vector<int> a;
int l = 0, r = a.size()-1;
int targe, id = a.size();
while (l <= r) {
int mid = l+r>>1;
if (a[mid] <= targe) { // 小于等于targe的数,小于则改为 a[mid] < targe
r = mid-1;
id = min(id, mid);
}
else {
l = mid+1;
}
}
是否存在
vector<int> a;
int l = 0, r = a.size()-1;
int targe;
while (l <= r) {
int mid = l+r>>1;
if (a[mid] == targe)
return true;
if (a[mid] < targe) l = mid+1;
else r = mid-1;
}
常见二分题
旋转升序数组找最小值
int minArray(vector<int>& numbers) {
int l = 0, r = numbers.size()-1;
while (l < r) {
int m = (l+r) >> 1;
if (numbers[m] > numbers[r]) l = m+1;
else if (numbers[m] < numbers[r]) r = m;
else --r;
}
return numbers[l];
}
旋转升序数组判断值
判断是否存在,存在返回下标,否则返回-1,数组无重复值
int search(vector<int>& nums, int target) {
if (nums.empty()) return -1;
if (nums.size() == 1) return nums[0] == target ? 0 : -1;
int l = 0, r = nums.size() - 1;
while (l <= r) {
int mid = l+r>>1;
if (nums[mid] == target) return mid;
if (nums[0] <= nums[mid]) {
if (nums[0] <= target && target < nums[mid])
r = mid - 1;
else l = mid + 1;
}
else {
if (nums[mid] < target && target <= nums.back())
l = mid + 1;
else r = mid - 1;
}
}
return -1;
}
判断是否存在,返回true或false,有重复值
bool search(vector<int> &nums, int target) {
if (nums.empty()) return false;
if (nums.size() == 1) return nums[0] == target;
int l = 0, r = nums.size()-1;
while (l <= r) {
int mid = l+r>>1;
if (nums[mid] == target)
return true;
if (nums[l] == nums[mid] && nums[mid] == nums[r]) {
++l;
--r;
}
else if (nums[l] <= nums[mid]) {
if (nums[l] <= target && target < nums[mid])
r = mid - 1;
else l = mid + 1;
}
else {
if (nums[mid] < target && target <= nums.back())
l = mid + 1;
else r = mid - 1;
}
}
return false;
}
二分sqrt
bool isSame(double a, double b) {
// 控制精度
if (abs(a-b) < 1e-8) return true;
return false;
}
double bin_sqrt(double x) {
// 当0<x<1时,x的开方会比x大
double left = 0, right = max(1.0, x);
// 必然有答案,循环控制等return即可
while (1) {
double mid = (left+right)/2.0;
double num = mid*mid;
if (isSame(num, x)) return mid;
else if (num < x) left = mid;
else right = mid;
}
return -1;
}