二分查找
二分查找就是比较高效的的查找算法。
一、二分查找
#include<iostream>
#include<vector>
using namespace std;
//缺点:遇到重复数字时,只能查找中间的目标数字
int search(vector<int>& nums, int target) {
int left=0,right=nums.size()-1,mid=0;
while(left<=right){ //=是为了防止漏掉left==right的情况
mid=left+(right-left)/2; //防止溢出
if(nums[mid]==target)
return mid;
//刚才的搜索区间是左闭右闭的
else if(nums[mid]<target)
left=mid+1;
else
right=mid-1;
}
return -1;
}
二、寻找左侧边界的二分搜索
int search(vector<int>& nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] == target) {
// 别返回,锁定左侧边界
right = mid - 1;
}
}
// 判断 target 是否存在于 nums 中
// 此时 target 比所有数都大,返回 -1
if (left == nums.length) return -1;
// 判断一下 nums[left] 是不是 target
return nums[left] == target ? left : -1;
}
三 、右侧边界的二分搜索
int search(vector<int>& nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] == target) {
// 别返回,锁定右侧边界
left = mid + 1;
}
}
// 此时 left - 1 索引越界
if (left - 1 < 0) return -1;
// 判断一下 nums[left] 是不是 target
return nums[left - 1] == target ? (left - 1) : -1;
}
高级函数
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
// 1.基础用法
vector<int> increasing = {1,2,3,4,5};
int pos = upper_bound(increasing.begin(), increasing.end(), 3) - increasing.begin();
cout << increasing[pos] << endl; // 4(第一个大于3的数)
pos = lower_bound(increasing.begin(), increasing.end(), 3) - increasing.begin();
cout << increasing[pos] << endl; // 3(第一个大于等于3的数)
bool res = upper_bound(increasing.begin(), increasing.end(), 5) == increasing.end();
cout << res << endl; // 1 (true,即:第一个大于5的数不存在)
// 2.greater重载
vector<int> decreasing = {5,4,3,2,1};
pos = upper_bound(decreasing.begin(), decreasing.end(), 3, greater<int>()) - decreasing.begin();
cout << decreasing[pos] << endl; // 2(第一个小于3的数)
pos = lower_bound(decreasing.begin(), decreasing.end(), 3, greater<int>()) - decreasing.begin();
cout << decreasing[pos] << endl; // 3(第一个小于等于3的数)
res = lower_bound(decreasing.begin(), decreasing.end(), 0, greater<int>()) == decreasing.end();
cout << res << endl; // 1 (true,即:第一个小于等于0的数不存在)
// 3.进阶用法
pos = upper_bound(increasing.begin(), increasing.end(), 3, [](int value, int element) -> bool {
return value < element;
}) - increasing.begin(); // 等价于基础用法中的第1句
cout << increasing[pos] << endl; // 4(value是3,第一个大于value的数)
pos = upper_bound(increasing.begin(), increasing.end(), 3, [](int value, int element) -> bool {
return value <= element;
}) - increasing.begin(); // 等价于基础用法中的第2句
cout << increasing[pos] << endl; // 3(value是3,第一个大于等于value的数)
pos = lower_bound(increasing.begin(), increasing.end(), 3, [](int element, int value) -> bool {
return element < value;
}) - increasing.begin(); // 等价于基础用法中的第2句
cout << increasing[pos] << endl; // 3(value是3,第一个大于等于value的数)
pos = lower_bound(increasing.begin(), increasing.end(), 3, [](int element, int value) -> bool {
return element <= value;
}) - increasing.begin(); // 等价于基础用法中的第1句
cout << increasing[pos] << endl; // 4(value是3,第一个大于value的数)
return 0;
}
作者:htcomeon
链接:https://leetcode.cn/circle/article/QKJ2g2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
总结
就这了,代码自己好好看看