zoukankan      html  css  js  c++  java
  • [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 and divide all the array by it and sum the result of the division. Find the smallest divisor such that the result mentioned above is less than or equal to threshold.

    Each result of division is rounded to the nearest integer greater than or equal to that element. (For example: 7/3 = 3 and 10/2 = 5).

    It is guaranteed 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 to 7 (1+1+2+3) and if the divisor is 5 the sum will be 5 (1+1+1+2). 
    

    Example 2:

    Input: nums = [2,3,5,7,11], threshold = 11
    Output: 3
    

    Example 3:

    Input: nums = [19], threshold = 5
    Output: 4

    Constraints:

    • 1 <= nums.length <= 5 * 10^4
    • 1 <= nums[i] <= 10^6
    • nums.length <= threshold <= 10^6

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

    给你一个整数数组 nums 和一个正整数 threshold  ,你需要选择一个正整数作为除数,然后将数组里每个数都除以它,并对除法结果求和。

    请你找出能够使上述结果小于等于阈值 threshold 的除数中 最小 的那个。

    每个数除以除数后都向上取整,比方说 7/3 = 3 , 10/2 = 5 。

    题目保证一定有解。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/find-the-smallest-divisor-given-a-threshold
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    思路是二分法。按照题意规定的计算方式,我们要找到一个合适的除数。但是如何确定除数的范围呢,下限肯定是1,上限应该是数组中最大的数字,我们暂且定义他为max。因为如果除数比max都大了,做如上那一通操作得出的除法结果求和只会是离 threshold 越来越远。

    确定好了除数的上限和下限之后,我们就可以开始做二分了。这里做二分没什么可说的,我们写一个helper函数,按照题意,每次找到一个mid,去计算那个所谓的sum是否是一个最大的且小于 threshold 的结果。

    时间O(nlog(max))

    空间O(1)

    Java实现

     1 class Solution {
     2     public int smallestDivisor(int[] nums, int threshold) {
     3         int max = 0;
     4         for (int num : nums) {
     5             max = Math.max(max, num);
     6         }
     7 
     8         int left = 1;
     9         int right = max;
    10         while (left < right) {
    11             int mid = left + (right - left) / 2;
    12             if (helper(nums, mid) > threshold) {
    13                 left = mid + 1;
    14             } else {
    15                 right = mid;
    16             }
    17         }
    18         return left;
    19     }
    20 
    21     private int helper(int[] nums, int divisor) {
    22         int sum = 0;
    23         for (int num : nums) {
    24             sum += num / divisor;
    25             // 不能整除的时候,需要向上取整
    26             if (num % divisor != 0) {
    27                 sum++;
    28             }
    29         }
    30         return sum;
    31     }
    32 }

    LeetCode 题目总结

  • 相关阅读:
    Linux PHP连接MSSQL
    Curl参数一览
    [android开发必备] Android开发者社区汇总
    android定时器
    一个mysql小技巧
    php empty问题
    周报_2012第16周(2012/04/152012/04/21)
    周报_2012第17周(2012/04/222012/04/28)
    周报_2013第04周(2013/01/202013/01/26)
    周报_2013第01周(2012/12/302012/01/05)
  • 原文地址:https://www.cnblogs.com/cnoodle/p/13940770.html
Copyright © 2011-2022 走看看