leetcode4
使结果不超过阈值的最小除数
给你一个整数数组 nums 和一个正整数 threshold ,你需要选择一个正整数作为除数,然后将数组里每个数都除以它,并对除法结果求和。
请你找出能够使上述结果小于等于阈值 threshold 的除数中 最小 的那个。
每个数除以除数后都向上取整,比方说 7/3 = 3 , 10/2 = 5 。
题目保证一定有解。
示例 1:
输入:nums = [1,2,5,9], threshold = 6 输出:5 解释:如果除数为 1 ,我们可以得到和为 17 (1+2+5+9)。 如果除数为 4 ,我们可以得到和为 7 (1+1+2+3) 。如果除数为 5 ,和为 5 (1+1+1+2)。
示例 2:
输入:nums = [2,3,5,7,11], threshold = 11 输出:3
示例 3:
输入:nums = [19], threshold = 5 输出:4
提示:
1 <= nums.length <= 5 * 10^41 <= nums[i] <= 10^6nums.length <= threshold <= 10^6
// 先是暴力循环,测试用例执行超时,后来用二分法没做出来
// 当时尝试中也尝试,结果+1 或者 结果-1,因为有个测试用例正好mid+1,但是,通过观察答案,它是left+1 或者是 right+1, 究其原因还是二分法还是没熟练得应用到实践 /** * @param {number[]} nums * @param {number} threshold * @return {number} */ var smallestDivisor = function(nums, threshold) { let len = nums.length; let max = Math.max(...nums); let n=0; let result; let left = 1; let right = max; if(len>=threshold){ return max; }else{ while(true){ let mid = Math.floor((right+left)/2) let res = nums.reduce((init, val)=>init+Math.ceil(val/mid), 0); if(res < threshold) { right = mid } else if(res > threshold){ left = mid } else if(res === threshold) { result = mid break; } if(mid === left ){ result = mid break; } if(mid === right){ result = mid break; } } } return result };
class Solution {
public:
int smallestDivisor(vector<int>& nums, int threshold) {
int L = 1, R = 1000001;
int ret = R;
while (L <= R)
{
int m = (L+R)/2;
long long sum = 0;
for (auto x : nums) sum += x/m+(x%m != 0);
if (sum <= threshold)
{
ret = m;
R = m-1;
}
else
L = m+1;
}
return ret;
}
};
/**
* @param {number[]} nums
* @param {number} threshold
* @return {number}
*/
var smallestDivisor = function(nums, threshold) {
let lo = 1
let hi = 1e6
while(lo <= hi) {
let mi = lo + Math.floor((hi - lo) / 2)
let c = check(mi)
// consol/e.log(mi, '->', c)
if (c > threshold) {
lo = mi + 1
} else {
hi = mi - 1
}
}
return hi + 1
function check(d) {
let ans = 0
for(const num of nums) {
ans += Math.ceil(num / d)
}
return ans
}
};
/** * @param {number[]} nums * @param {number} threshold * @return {number} */ var smallestDivisor = function(nums, threshold) { let l = 0; let r = 1000000; while (l < r) { const m = Math.round((l + r) / 2); let sum = 0; for (let i = 0; i < nums.length; i++) { sum += Math.ceil(nums[i] / m); } if (sum <= threshold) { r = m - 1; } else { l = m; } } return l + 1; };

浙公网安备 33010602011771号