[LeetCode] 1760. Minimum Limit of Balls in a Bag

You are given an integer array nums where the ith bag contains nums[i] balls. You are also given an integer maxOperations.

You can perform the following operation at most maxOperations times:

  • Take any bag of balls and divide it into two new bags with a positive number of balls.
    • For example, a bag of 5 balls can become two new bags of 1 and 4 balls, or two new bags of 2 and 3 balls.

Your penalty is the maximum number of balls in a bag. You want to minimize your penalty after the operations.

Return the minimum possible penalty after performing the operations.

Example 1:

Input: nums = [9], maxOperations = 2
Output: 3
Explanation: 
- Divide the bag with 9 balls into two bags of sizes 6 and 3. [9] -> [6,3].
- Divide the bag with 6 balls into two bags of sizes 3 and 3. [6,3] -> [3,3,3].
The bag with the most number of balls has 3 balls, so your penalty is 3 and you should return 3.

Example 2:

Input: nums = [2,4,8,2], maxOperations = 4
Output: 2
Explanation:
- Divide the bag with 8 balls into two bags of sizes 4 and 4. [2,4,8,2] -> [2,4,4,4,2].
- Divide the bag with 4 balls into two bags of sizes 2 and 2. [2,4,4,4,2] -> [2,2,2,4,4,2].
- Divide the bag with 4 balls into two bags of sizes 2 and 2. [2,2,2,4,4,2] -> [2,2,2,2,2,4,2].
- Divide the bag with 4 balls into two bags of sizes 2 and 2. [2,2,2,2,2,4,2] -> [2,2,2,2,2,2,2,2].
The bag with the most number of balls has 2 balls, so your penalty is 2, and you should return 2.

Constraints:

  • 1 <= nums.length <= 105
  • 1 <= maxOperations, nums[i] <= 109

袋子里最少数目的球。

给你一个整数数组 nums ,其中 nums[i] 表示第 i 个袋子里球的数目。同时给你一个整数 maxOperations 。

你可以进行如下操作至多 maxOperations 次:

选择任意一个袋子,并将袋子里的球分到 2 个新的袋子中,每个袋子里都有 正整数 个球。
比方说,一个袋子里有 5 个球,你可以把它们分到两个新袋子里,分别有 1 个和 4 个球,或者分别有 2 个和 3 个球。
你的开销是单个袋子里球数目的 最大值 ,你想要 最小化 开销。

请你返回进行上述操作后的最小开销。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minimum-limit-of-balls-in-a-bag
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路是二分,不是很容易能想到,我直接讲做法。因为题目给定了最多的操作次数,记为 maxOperations,所以我们的二分是在答案上二分 - 意思是用二分在 1 - Integer.MAX_VALUE 这个区间内尝试一个值,然后看看以这个值作为开销 penalty,所对应的操作次数是多少,如果这个操作次数超过了 maxOperations,就需要移动 left 指针,说明为了满足当前这个开销,操作次数超过上限了;反之移动 right 指针,说明开销可以试着更小一点。

时间O(nlogn)

空间O(1)

Java实现

 1 class Solution {
 2     public int minimumSize(int[] nums, int maxOperations) {
 3         int left = 1;
 4         int right = Integer.MAX_VALUE;
 5         while (left < right) {
 6             int mid = left + (right - left) / 2;
 7             int count = 0;
 8             for (int num : nums) {
 9                 count += (num - 1) / mid;
10             }
11             if (count > maxOperations) {
12                 left = mid + 1;
13             } else {
14                 right = mid;
15             }
16         }
17         return left;
18     }
19 }

 

LeetCode 题目总结

posted @ 2022-12-20 12:59  CNoodle  阅读(66)  评论(0编辑  收藏  举报