这段代码是一个 C++ 实现,旨在找到一个最小的除数,使得将 nums
中的每个元素除以这个除数后的结果之和不超过给定的阈值 threshold
。代码主要使用二分查找来高效地找到这个最小的除数。
代码分析
函数
possible
:- 输入: 一个整数向量
nums
、一个整数threshold
和一个整数divisor
。 - 功能: 计算将
nums
中每个元素用divisor
除后向上取整得到的和,并判断是否小于或等于threshold
。 - 实现:
(x - 1) / divisor + 1
等价于向上取整,因为(x + divisor - 1) / divisor
可以用简单运算实现。
- 输入: 一个整数向量
函数
smallestDivisor
:- 输入: 一个整数向量
nums
和一个整数threshold
。 - 功能: 使用二分查找确定满足条件的最小除数。
- 初始化左右边界:左边界为 1(不能为0),右边界为数组中的最大值加一。
- 在循环中,通过调用
possible()
来检查当前中间值是否符合要求:- 如果符合,将右边界移动到中间值左侧,寻找更小的除数。
- 如果不符合,则将左边界移动到中间值右侧。
- 输入: 一个整数向量
返回: 最终返回找到的最小除数。
完整代码
#include <vector>
#include <algorithm>
using namespace std;
bool possible(vector<int>& nums, int threshold, int divisor) {
int sum = 0;
for (int x : nums) {
sum += (x - 1) / divisor + 1;
}
return sum <= threshold;
}
int smallestDivisor(vector<int>& nums, int threshold) {
int max_val = *max_element(nums.begin(), nums.end());
int left = 1, right = max_val; // left 从1开始,right是最大值
while (left < right) {
int mid = left + (right - left) / 2; // 防止溢出
if (possible(nums, threshold, mid)) {
right = mid; // 找到可能,更大的mid可能也可行
} else {
left = mid + 1; // 否则,需要更大的mid
}
}
return left; // 返回最终找到的最小除数
}
注意事项
- 确保输入数据合法性,例如确保数组非空且阈值大于零等。
- 边界条件处理,如当所有数字都较小时,以及选择合适的数据类型以防止溢出。
内容由零声教学AI助手提供,问题来源于学员提问