1071 字
5 分钟
C++ 中二分查找库函数
2025-04-10

函数简介#

C++ 标准库中提供了三个和二分查找相关的函数,都定义在 头文件中,非常实用而且高效,下面是它们的功能和使用方法:

 判断某个元素是否存在于有序数组中

#include

bool found = binary_search(nums.begin(), nums.end(), target);

• 返回值:true 表示找到了 target,否则为 false。
• 时间复杂度:O(log n)

✅ 2. lower_bound#

 查找第一个 大于等于 target 的元素的位置(返回迭代器)

auto it = lower_bound(nums.begin(), nums.end(), target);

int index = it - nums.begin(); // 获取下标

• 如果 target 存在,返回它的第一个出现位置;
• 如果不存在,返回第一个大于 target 的元素位置;
• 若返回 nums.end(),说明没有比 target 大或等于它的元素。

✅ 3. upper_bound#

 查找第一个 大于 target 的元素的位置(返回迭代器)

auto it = upper_bound(nums.begin(), nums.end(), target);

int index = it - nums.begin(); // 获取下标

• 如果 target 存在多次,upper_bound 返回的是最后一个的下一个位置;
• 若返回 nums.end(),说明所有元素都 ≤ target。

 三者比较总结:#

函数名 返回含义 用法 时间复杂度

binary_search 是否存在 target binary_search(v.begin(), v.end(), x) O(log n)

lower_bound 第一个 ≥ target 的位置 lower_bound(v.begin(), v.end(), x) O(log n)

upper_bound 第一个 > target 的位置 upper_bound(v.begin(), v.end(), x) O(log n)

離 举个例子:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> nums = {1, 2, 4, 4, 5, 6};
int target = 4;
cout << binary_search(nums.begin(), nums.end(), target) << endl; // 1 (true)
cout << lower_bound(nums.begin(), nums.end(), target) - nums.begin() << endl; // 2
cout << upper_bound(nums.begin(), nums.end(), target) - nums.begin() << endl; // 4
return 0;
}

适用场景#

里 示例 1:插入一个数使数组仍然有序#

vector<int> nums = {1, 3, 5, 7};
int target = 4;
// 插入 target 保持升序
auto it = lower_bound(nums.begin(), nums.end(), target);
nums.insert(it, target); // 插入到合适位置
// 结果:nums = {1, 3, 4, 5, 7}
###  示例 2:查找数组中第一个 ≥ target 的元素

vector nums = {1, 3, 5, 7, 9}; int target = 6;

auto it = lower_bound(nums.begin(), nums.end(), target);

if (it != nums.end()) { cout << “第一个 ≥ ” << target << ” 的元素是 ” << *it << endl; } else { cout << “所有元素都小于 ” << target << endl; }

 示例 3:查找数组中第一个 > target 的元素#

vector<int> nums = {1, 3, 5, 7, 9};
int target = 5;
auto it = upper_bound(nums.begin(), nums.end(), target);
if (it != nums.end()) {
cout << "第一个 > " << target << " 的元素是 " << *it << endl;
}
###  示例 4:查找元素出现的次数(重复元素)

vector nums = {1, 3, 3, 3, 5, 7}; int target = 3;

// 出现次数 = upper_bound - lower_bound int count = upper_bound(nums.begin(), nums.end(), target) - lower_bound(nums.begin(), nums.end(), target);

cout << “数字 ” << target << ” 出现了 ” << count << ” 次” << endl;

 示例 5:查找离 target 最近的数#

vector<int> nums = {1, 3, 6, 8, 10};
int target = 5;
auto it = lower_bound(nums.begin(), nums.end(), target);
int closest;
if (it == nums.begin()) {
closest = *it;
} else if (it == nums.end()) {
closest = *(--it);
} else {
int a = *it;
int b = *(--it);
closest = (abs(a - target) < abs(b - target)) ? a : b;
}
cout << "离 " << target << " 最近的数是 " << closest << endl;

例题#

https://leetcode.cn/problems/maximum-count-of-positive-integer-and-negative-integer/

给你一个按 非递减顺序 排列的数组 nums ,返回正整数数目和负整数数目中的最大值。

换句话讲,如果 nums 中正整数的数目是 pos ,而负整数的数目是 neg ,返回 pos 和 neg二者中的最大值。

注意:0 既不是正整数也不是负整数。

示例 1:

输入:nums = [-2,-1,-1,1,2,3]

输出:3

解释:共有 3 个正整数和 3 个负整数。计数得到的最大值是 3 。

示例 2:

输入:nums = [-3,-2,-1,0,0,1,2]

输出:3

解释:共有 2 个正整数和 3 个负整数。计数得到的最大值是 3 。

示例 3:

输入:nums = [5,20,66,1314]

输出:4

解释:共有 4 个正整数和 0 个负整数。计数得到的最大值是 4 。

提示:

1 <= nums.length <= 2000

-2000 <= nums[i] <= 2000

nums 按 非递减顺序 排列。

进阶:你可以设计并实现时间复杂度为 O(log(n)) 的算法解决此问题吗?

#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
int maximumCount(vector<int>& nums) {
// 统计负数:最后一个 <0 的位置 +1
int neg = upper_bound(nums.begin(), nums.end(), -1) - nums.begin();
// 统计正数:end - 第一个 >0 的位置
int pos = nums.end() - lower_bound(nums.begin(), nums.end(), 1);
return max(neg, pos);
}
};

原文发布于 CSDN:C++ 中二分查找库函数

C++ 中二分查找库函数
https://www.tommywutong.cn/posts/csdn-import/csdn-147111379-c-/
作者
TommyWu
发布于
2025-04-10
许可协议
CC BY-NC-SA 4.0