目录
题目解析:最小化拆分袋子中球的最大数量
题目描述
给你一个整数数组 nums
,其中 nums[i]
表示第 i
个袋子里球的数目。同时给你一个整数 maxOperations
。
你可以进行如下操作最多 maxOperations
次:
- 选择任意一个袋子,将袋子里的球分到 2 个新的袋子中,每个新袋子里都有 正整数 个球。
例如,一个袋子里有 5 个球,可以拆分成两个新袋子,分别有 1 个和 4 个球,或者分别有 2 个和 3 个球。
你的目标是最小化拆分操作后,所有袋子中球数目的最大值(即开销)。
请你返回这个最小的最大球数。
题目示例
示例 1
输入:nums = [9], maxOperations = 2
输出:3
解释:
- 第一次拆分:9 -> 6 和 3
- 第二次拆分:6 -> 3 和 3
拆分后袋子分别为 [3,3,3],最大袋子球数为 3,返回 3。
示例 2
输入:nums = [2,4,8,2], maxOperations = 4
输出:2
解释:
- 将8拆成4和4:[2,4,4,4,2]
- 拆4成2和2:[2,4,4,4,2] -> [2,2,2,4,4,2]
- 再拆两个4为2和2,最多拆4次
最终所有袋子最大球数为2。
示例 3
输入:nums = [7,17], maxOperations = 2
输出:7
解题分析
这道题的核心在于,给定一个限制的最大袋子容量 x
,判断是否能通过最多 maxOperations
次拆分,将所有袋子的球数都控制在 x
以下。然后利用二分搜索寻找最小的 x
。
为什么使用二分搜索?
- 开销范围:最大开销的最小值至少是 1(每袋至少有1个球),最大值是
max(nums)
(不拆分的最大袋子数)。 - 单调性:如果最大容量限制为
x
可以完成拆分,那么任何大于x
的容量也肯定可以完成拆分;反之,不可行。 - 因此,答案在
[1, max(nums)]
这个区间内具有单调性质,可以用二分搜索找最小可行解。
如何判断可行?
对每个袋子:
- 若袋子里球数
num <= x
,不需要拆分,操作数为0。 - 若
num > x
,需要拆分成若干个不超过x
的袋子。
拆分次数计算方法:
- 袋子拆成的袋子数 =
ceil(num / x)
,拆分次数 = 拆成的袋子数 - 1 - 数学表达式:拆分次数 =
(num - 1) // x
累加所有袋子的拆分次数,若总拆分次数 ≤ maxOperations
,说明 x
是可行的。
解题方法(代码)
from typing import List
class Solution:
def minimumSize(self, nums: List[int], maxOperations: int) -> int:
def can_split(max_size):
operations = 0
for num in nums:
# 拆分次数 = (num - 1) // max_size
operations += (num - 1) // max_size
if operations > maxOperations:
return False
return True
left, right = 1, max(nums)
while left < right:
mid = (left + right) // 2
if can_split(mid):
right = mid
else:
left = mid + 1
return left
复杂度分析
- 时间复杂度:
-
- 二分搜索的范围为
[1, max(nums)]
,假设最大球数为m
,则二分搜索最多进行O(log m)
次。 - 每次判断需要遍历所有袋子,时间为
O(n)
。 - 总时间复杂度为
O(n log m)
。
- 二分搜索的范围为
- 空间复杂度:
-
- 只使用了常数额外空间,空间复杂度为
O(1)
。
- 只使用了常数额外空间,空间复杂度为
示例说明与验证
以示例 1 为例:
nums = [9]
,maxOperations = 2
- 搜索范围:1 到 9
尝试中间值:
- mid=5,拆分9:需要
(9-1)//5=1
次拆分,1 <= 2 可行,右边界收缩到5 - mid=3,拆分9:
(9-1)//3=2
次拆分,2 <= 2 可行,右边界收缩到3 - mid=2,拆分9:
(9-1)//2=4
次拆分,4 > 2 不可行,左边界收缩到3
最终左边界3,即最小最大开销为3。
总结
这道题通过二分搜索 + 贪心拆分实现高效求解,关键是:
- 明确目标函数是“最大袋子球数”的最小值。
- 利用二分搜索缩小答案范围。
- 设计一个判断函数,根据给定最大容量判断是否能在操作限制内拆分完成。
该题模式在很多分割、拆分和最大容量限制类问题中常见,掌握该方法有助于解决类似题目。