二分查找
二分查找(Binary Search)是一种高效的查找算法,用于在已排序的数组或列表中查找特定元素。它的基本思想是通过将查找区间不断折半来缩小范围,从而快速定位目标元素。以下是二分查找的基本步骤:
-
初始化:设置两个指针,分别指向数组的开始和结束位置。通常用
left指向数组的第一个元素,right指向数组的最后一个元素。 -
循环查找:
-
计算中间位置
mid,通常使用公式mid = left + (right - left) / 2。 -
检查中间元素
array[mid]:- 如果它等于目标元素,查找成功,返回
mid。 - 如果目标元素小于中间元素,将
right指针移动到mid - 1。 - 如果目标元素大于中间元素,将
left指针移动到mid + 1。
- 如果它等于目标元素,查找成功,返回
-
-
结束条件:当
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计算在每个背包的最大承重范围内,最多可以带走多少块巧克力板。每块巧克力的重量是其边长的平方。
数据结构选择
- 巧克力板数组:
vector<int> a,存储每块巧克力的边长。 - 背包承重数组:
vector<int> queries,存储每个背包的最大承重。 - 结果数组:
vector<int> result,存储每个背包最多能装入的巧克力块数。
算法步骤
-
排序巧克力板:首先,对巧克力板按重量(即边长的平方)进行排序。这样可以更容易地选择重量较小的巧克力板。
-
计算每个背包的结果:
- 对于每个背包的最大承重,从排序后的巧克力板中选择尽可能多的巧克力板,直到超过背包的承重限制。
- 记录每个背包最多能装入的巧克力块数。
具体步骤
-
排序巧克力板:按边长的平方进行排序。
-
遍历每个背包:
- 初始化当前背包的承重为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;
}