二分法查找边界

使用示例

vector<int> nums = {1, 2, 2, 2, 3, 4, 5};
int target = 2;

cout << "第一个 >= 2: " << lowerBound(nums, target) << endl;        // 1
cout << "第一个 > 2: " << upperBound(nums, target) << endl;         // 4
cout << "最后一个 <= 2: " << lastLessEqual(nums, target) << endl;   // 3
cout << "最后一个 < 2: " << lastLess(nums, target) << endl;         // 0

记忆技巧

查找类型条件判断返回值等价关系
第一个 >= targetnums[mid] < targetleftlower_bound
第一个 > targetnums[mid] <= targetleftupper_bound
最后一个 <= targetnums[mid] <= targetleft - 1upper_bound - 1
最后一个 < targetnums[mid] < targetleft - 1lower_bound - 1

所有实现都使用左闭右开区间 [left, right),保持一致性。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/**************************************************************** 
 * 代码作者: Alex Li
 * 创建时间: 2025-09-03 01:06:56
 * 最后修改: 2025-09-03 01:10:23
 * 文件描述: 二分法查找边界
****************************************************************/
#include <iostream>
#include <vector>
using namespace std;

// 1. 第一个 >= target
int lowerBound(vector<int>& nums, int target) {
    int left = 0, right = nums.size(); // [left, right)
    while (left < right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
            left = mid + 1; 
        } else {
            right = mid; 
        }
    }
    return left; // 或 right
}

// 2. 第一个 > target
int upperBound(vector<int>& nums, int target) {
    int left = 0, right = nums.size(); // [left, right)
    while (left < right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] <= target) {
            left = mid + 1; 
        } else {
            right = mid; 
        }
    }
    return left; // 或 right
}

// 3. 最后一个 <= target
int lastLE(vector<int>& nums, int target) {
    int left = 0, right = nums.size(); // [left, right)
    while (left < right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] <= target) {
            left = mid + 1; 
        } else {
            right = mid; 
        }
    }
    return left - 1; // 注意:可能为 -1
}

// 4. 最后一个 < target
int lastLT(vector<int>& nums, int target) {
    int left = 0, right = nums.size(); // [left, right)
    while (left < right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
            left = mid + 1; 
        } else {
            right = mid; 
        }
    }
    return left - 1; // 注意:可能为 -1
}

int main() {
    int n,target;
    cout<<"input nubmer: ";
    cin>>n;
    vector<int> nums(n);
    for (int k =0; k < n; ++k) {
        cin>>nums[k];
        }
   // sort(a.begin(),a.end());  //如果输入数组不保证升序,就排序。
    cout<<"input number that your want to find: ";
    cin>>target;

    cout << "lowerBound (>= " << target << "): " << lowerBound(nums, target) << endl;
    cout << "upperBound (>  " << target << "): " << upperBound(nums, target) << endl;
    cout << "lastLE     (<= " << target << "): " << lastLE(nums, target) << endl;
    cout << "lastLT     (<  " << target << "): " << lastLT(nums, target) << endl;

    return 0;
}
Scroll to Top