LEETCODE 1283. Find the Smallest Divisor Given a Threshold 解题思路分析

题目大意:

使结果不超过阈值的最小除数

给你一个整数数组 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^4
  • 1 <= nums[i] <= 10^6
  • nums.length <= threshold <= 10^6

如果想查看本题目是哪家公司的面试题,请参考以下免费链接: https://leetcode.jp/problemdetail.php?id=1283

解题思路分析:

这是一道典型的并且容易联想到使用二分查找来解题的题目。二分查找的范围在1到max之间。max为数组中的最大数。我们利用这些数字作为除数,用每个数字除以当前除数,算出所有商的和,与threshold比较,如果和大于threshold,需要减小和,也就是相应增大除数,反之减小除数。编写二分查找时注意边界问题。

实现代码:

public int smallestDivisor(int[] nums, int threshold) {
    int max = -1; // 数组中的最大数
    // 找到数组中的最大数
    for (int n : nums) max = Math.max(max, n);
    // 左边界为1,右边界为数组中最大数,开始二分查找
    int left=1, right=max;
    while(left<right){
        // 中间值
        int mid=(left+right)/2;
        // 求所有商的和
        int sum=0;
        for(int n : nums){
            sum+=((n+mid-1) / mid);
        }
        // 如果和小于等于threshold,增大除数
        if(sum<=threshold){
            right=mid;
        }else{
        // 反之,减少除数
            left=mid+1;
        }
    }
    return left;
}

本题解法执行时间为10ms。

Runtime: 10 ms, faster than 100.00% of Java online submissions for Find the Smallest Divisor Given a Threshold.

Memory Usage: 42.9 MB, less than 100.00% of Java online submissions for Find the Smallest Divisor Given a Threshold.

本网站文章均为原创内容,并可随意转载,但请标明本文链接
如有任何疑问可在文章底部留言。为了防止恶意评论,本博客现已开启留言审核功能。但是博主会在后台第一时间看到您的留言,并会在第一时间对您的留言进行回复!欢迎交流!
本文链接: https://leetcode.jp/leetcode-1283-find-the-smallest-divisor-given-a-threshold-解题思路分析/
此条目发表在leetcode分类目录,贴了, , 标签。将固定链接加入收藏夹。

发表评论

您的电子邮箱地址不会被公开。