二分查找

二分查找或返回插入位置

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    int n, target;
    cin >> n >> target;
    vector<int> nums(n);

    for (int i = 0; i < n; ++i)
    {
        cin >> nums[i];
    }

    int left = 0;
    int right = n; // 左闭右开区间 [left, right)
    bool found = false;

    while (left < right)
    {
        int mid = left + (right - left) / 2; // 防止溢出,推荐写法

        if (nums[mid] == target)
        {
            cout << mid << endl;
            found = true;
            break; // 找到就立即退出
        }
        else if (nums[mid] > target)
        {
            right = mid; // 舍弃右半边(包含 mid)
        }
        else
        {
            left = mid + 1; // 舍弃左半边(不含 mid)
        }
    }

    if (!found)
    {
        // 没找到,输出应该插入的位置
        cout << left << endl;
    }

    return 0;
}

📝 二分查找模板关键笔记(适用于面试/刷题)

🔹 1. 区间定义一定要搞清楚:左闭右开 [left, right)

  • 设定 right = n,而不是 n - 1,避免遗漏最后一个元素。
  • 循环条件是 left < right,即还有搜索空间时继续。

🔹 2. mid 的计算必须写在循环体内!

  • 每次 leftright 变化后,mid 也必须重新计算:
    int mid = left + (right - left) / 2;
    
  • 推荐使用这个写法而不是 (left + right) / 2,防止大数加法溢出。

🔹 3. 找到目标后要记得及时 break

  • nums[mid] == target,输出并立刻 break,避免进入多余循环。
  • 避免写错逻辑导致死循环。

🔹 4. 没找到目标时返回插入位置(left

  • 此逻辑类似于 C++ lower_bound() 的行为。
  • left 最终会落在第一个大于等于 target 的位置。

📚 延伸提示(进阶):

  • 若要查找最右侧的相等元素(upper bound),left = mid + 1right = n 的策略仍适用,但判断逻辑略有不同。
  • 二分查找不仅用于查数字,还可以用于函数、浮点、字符串的“最小值最大值”搜索(如“最小化最大值”类题型)。

posted @ 2025-04-29 22:55  vv大人  阅读(42)  评论(0)    收藏  举报