每日一水(二分查找) | 豆包MarsCode AI刷题

46 阅读3分钟

二分查找

二分查找(Binary Search)是一种高效的查找算法,用于在已排序的数组或列表中查找特定元素。它的基本思想是通过将查找区间不断折半来缩小范围,从而快速定位目标元素。以下是二分查找的基本步骤:

  1. 初始化:设置两个指针,分别指向数组的开始和结束位置。通常用 left 指向数组的第一个元素,right 指向数组的最后一个元素。

  2. 循环查找

    • 计算中间位置 mid,通常使用公式 mid = left + (right - left) / 2

    • 检查中间元素 array[mid]

      • 如果它等于目标元素,查找成功,返回 mid
      • 如果目标元素小于中间元素,将 right 指针移动到 mid - 1
      • 如果目标元素大于中间元素,将 left 指针移动到 mid + 1
  3. 结束条件:当 left 指针超过 right 指针时,表示未找到目标元素,返回一个表示找不到的值(通常是 -1)。

下面来一道水题帮助理解

问题描述

小M在春游时打算携带尽可能多的巧克力板。她拥有n块巧克力板,每块巧克力的边长为aiai​,重量为ai2ai2​。小M有多个不同大小的背包,每个背包都有一定的最大承重限制。她希望你帮助她计算在每个背包的最大承重范围内,最多可以带走多少块巧克力板。

例如:小M有5块巧克力板,边长分别为1, 2, 2, 4, 5,有5个不同的背包,其最大承重分别为1, 3, 7, 9, 15。对于每个背包,她能装入的巧克力块数分别是1, 1, 2, 3, 3

问题理解

你需要帮助小M计算在每个背包的最大承重范围内,最多可以带走多少块巧克力板。每块巧克力的重量是其边长的平方。

数据结构选择

  1. 巧克力板数组vector<int> a,存储每块巧克力的边长。
  2. 背包承重数组vector<int> queries,存储每个背包的最大承重。
  3. 结果数组vector<int> result,存储每个背包最多能装入的巧克力块数。

算法步骤

  1. 排序巧克力板:首先,对巧克力板按重量(即边长的平方)进行排序。这样可以更容易地选择重量较小的巧克力板。

  2. 计算每个背包的结果

    • 对于每个背包的最大承重,从排序后的巧克力板中选择尽可能多的巧克力板,直到超过背包的承重限制。
    • 记录每个背包最多能装入的巧克力块数。

具体步骤

  1. 排序巧克力板:按边长的平方进行排序。

  2. 遍历每个背包

    • 初始化当前背包的承重为0。
    • 遍历排序后的巧克力板,尝试将巧克力板放入背包,直到超过背包的承重限制。
    • 记录当前背包最多能装入的巧克力块数。
下面是代码
vector<int> solution(int n, int m, vector<int> a, vector<int> queries) {
    // 1. 对巧克力板按边长的平方进行排序
    sort(a.begin(), a.end(), [](int x, int y) {
        return x * x < y * y; // 按边长的平方排序
    });

    vector<int> result;

    // 2. 遍历每个背包
    for (int max_weight : queries) {
        int current_weight = 0;
        int count = 0;

        // 3. 尝试将巧克力板放入背包
        for (int side_length : a) {
            int weight = side_length * side_length;
            if (current_weight + weight <= max_weight) {
                current_weight += weight;
                count++;
            } else {
                break; // 超过背包承重,停止放入
            }
        }

        // 4. 记录当前背包最多能装入的巧克力块数
        result.push_back(count);
    }

    return result;
}