zoukankan      html  css  js  c++  java
  • 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
    class Solution {
        public int smallestDivisor(int[] nums, int threshold) {
            Arrays.sort(nums);
            int max = nums[nums.length - 1];
            int res = Integer.MAX_VALUE;
            for(int i = 1; i <= max; i++){
                int sum = 0;
                for(int j = 0; j < nums.length; j++){
                    if(nums[j] < i) sum += 1;
                    else if(nums[j] % i == 0) sum += nums[j] / i;
                    else sum += nums[j] / i + 1;
                }
                if(threshold >= sum){
                    res = Math.min(i, res);
                }
            }
            return res;
        }
    }

    O(n2) TLE sadly.

    再看了hint,发现是二分法,想来也对。

    首先在除法种除数divisor越小,商越大。我们是要商的sum小于threshold的前提下,所有divisor的sum最小,

    从中间开始,如果得到商的sum大于thresold说明除数太小了,mid+1,

    如果sum小于threshold说明还可以接受,mid-1

    class Solution {
        public int smallestDivisor(int[] nums, int threshold) {
            Arrays.sort(nums);
            int right = nums[nums.length - 1];
            int left = 1;
            while(left < right){
                int m = left + (right - left)/2, sum = 0;
                for(int j = 0; j < nums.length; j++){
                if(nums[j] % m == 0) sum += nums[j] / m;
                    else sum += nums[j] / m + 1;
                }
                if(sum > threshold) left = m + 1;
                else right = m;
            }
            return left;
        }
    }

    方法2,pass,有点慢,因为用了sort方法

    class Solution {
        public int smallestDivisor(int[] nums, int threshold) {
            
            int right = (int)1e6;
            int left = 1;
            while(left < right){
                int m = left + (right - left)/2, sum = 0;
                for(int j = 0; j < nums.length; j++){
                if(nums[j] % m == 0) sum += nums[j] / m;
                    else sum += nums[j] / m + 1;
                }
                //for(int i : nums) sum += (i + m - 1) / m;
                if(sum > threshold) left = m + 1;
                else right = m;
            }
            return left;
        }
    }

    方法3,快了点

     public int smallestDivisor(int[] A, int threshold) {
            int left = 1, right = (int)1e6;
            while (left < right) {
                int m = (left + right) / 2, sum = 0;
                for (int i : A)
                    sum += (i + m - 1) / m;
                if (sum > threshold)
                    left = m + 1;
                else
                    right = m;
            }
            return left;
        }

    方法4最快,来自https://leetcode.com/problems/find-the-smallest-divisor-given-a-threshold/discuss/446376/JavaC%2B%2BPython-Binary-Search

  • 相关阅读:
    BN
    框架中的DDP和buffer
    深度学习框架中的并行
    Transformer
    自监督表示学习Paper
    半监督学习paper阅读
    目标检测经典paper
    STM32_从SystemInit、__main到main() 已修正
    STM32启动代码分析及其汇编学习-ARM
    Rust 及其包管理Cargo的安装使用
  • 原文地址:https://www.cnblogs.com/wentiliangkaihua/p/12065983.html
Copyright © 2011-2022 走看看