[LeetCode] 1283. Find the Smallest Divisor Given a Threshold 使结果不超过阈值的最小除数
Given an array of integers nums
and an integer threshold
, we will choose a positive integer divisor
, divide all the array by it, and sum the division's result. Find the smallest divisor
such that the result mentioned above is less than or equal to threshold
.
Each result of the division is rounded to the nearest integer greater than or equal to that element. (For example: 7/3 = 3
and 10/2 = 5
).
The test cases are generated so that there will be an answer.
Example 1:
Input: nums = [1,2,5,9], threshold = 6
Output: 5
Explanation: We can get a sum to 17 (1+2+5+9) if the divisor is 1.
If the divisor is 4 we can get a sum of 7 (1+1+2+3) and if the divisor is 5 the sum will be 5 (1+1+1+2).
Example 2:
Input: nums = [44,22,33,11,1], threshold = 5
Output: 44
Constraints:
1 <= nums.length <= 5 * 10^4
1 <= nums[i] <= 10^6
nums.length <= threshold <= 10^6
这道题给了一个整型数组 nums,一个正整数 threshold,让找到一个最小的除数,使得数组中的每个数字除以这个 divisor 的商之和小于等于给定的 threshold。这里对于除不尽的情况下是采取 ceiling 的取整方式,而且题目中说了一定会有解。通过观察题目中给的例子不难理解题意,现在再来想一想需要返回的这个数有没有什么范围,首先题目中说了必须是一个正数,而最小的正数是1,什么情况下可能返回1呢?数组中所有的数字除以1都是其本身,那么商之和就等于数组之和,即原数组之和小于等于 threshold 时,就可以返回1,这是返回值的最小值。而最大值则可以取到数组中的最大值,因为再大就没有意义了,得到的商还是1,即商之和为数组的元素个数,其必定小于等于 threshold,因为题目说一定有解。
返回值的范围有了,为 [1, 10^6],可以发现是有序的,那么隐隐约约可以感觉到应该可以用二分搜索法来查找吧,因为一个一个的检测实在是不高效,当得到二分搜索的中间值 mid 时,遍历数组中的每个数字,计算商。由于需要在不能整除时进行 ceiling 取整,这里可以使用一个小 trick,先給 num 加上一个 mid-1, 然后再除以 mid,这样就是得到 ceiling 取整的结果了,对于可以整除的 num,得到还是整除后的商,并不会改变。然后用商之和 sum 跟 threshold 进行比较,若大于 threshold,则表示除数小了,将 left 更新为 mid+1,反之,则将 right 更新为 mid,最终的结果保存在了 left 中。这道题是博主的总结帖 LeetCode Binary Search Summary 二分搜索法小结 中的第四类,参见代码如下:
class Solution {
public:
int smallestDivisor(vector<int>& nums, int threshold) {
int left = 1, right = 1e6;
while (left < right) {
int mid = left + (right - left) / 2, sum = 0;
for (int num : nums) {
sum += (num + mid - 1) / mid;
}
if (sum > threshold) left = mid + 1;
else right = mid;
}
return left;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/1283
类似题目:
Minimized Maximum of Products Distributed to Any Store
参考资料:
https://leetcode.com/problems/find-the-smallest-divisor-given-a-threshold/