算法日志 --- 12.19---袋子里最少数目的球

94 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第26天,点击查看活动详情

今天的自己依旧是不能上班,还是处于居家的状态

袋子里最少数目的球

该题出自力扣的1760题 —— 袋子里最少数目的球【中等题】

审题

给你一个整数数组 nums ,其中 nums[i] 表示第 i 个袋子里球的数目。同时给你一个整数 maxOperations 。 你可以进行如下操作至多 maxOperations 次: 选择任意一个袋子,并将袋子里的球分到 2 个新的袋子中,每个袋子里都有 正整数 个球。 比方说,一个袋子里有 5 个球,你可以把它们分到两个新袋子里,分别有 1 个和 4 个球,或者分别有 2 个和 3 个球。 你的开销是单个袋子里球数目的 最大值 ,你想要 最小化 开销。 请你返回进行上述操作后的最小开销。

  • 这道题的意思确实很经典,但是就要看是否能辨别出来,二分查找,凡是提到要返回最大的最小值或者最小的最大值的都是可以利用二分查找去解决
  • 给出一个整型数组,数组内包含的值是指一个袋子内存在的球数量,maxOerations变量是指需要操作的次数,最终返回的是袋子内最大的球数量
  • 利用二分查找的解题思路,计算出mid值 —— 也就是如果mid作为最大值,每个元素是否会超过这个操作数
  • 如果超过了意味着这个mid值定的太大了,其实就是利用二分去猜
  • 二分单个袋子里面的球的个数的最大值,也就是袋子容量,然后判断此次的操作数有没有大于最大操作数

编码

class Solution {
    public int minimumSize(int[] nums, int maxOperations) {
        int l = 1,r = Arrays.stream(nums).max().getAsInt();
        int ans = 0;
        while (r >= l){
            int mid = l + ((r -l) >> 1);
            long ops = 0;
            for (int x : nums) {
                ops += (x - 1) / mid;
            }
            if (ops <= maxOperations) {
                ans = mid;
                r = mid - 1;
            } else {
                l = mid + 1;
            }
        }
        return ans;
    }
}

image.png