📅  最后修改于: 2023-12-03 15:25:19.610000             🧑  作者: Mango
给定一个整数数组 nums 和一个正整数 K,将数组拆分为 K 个不重叠的子集,使得所有子集和中的最大值最小。
此问题属于搜索和二分的结合。首先我们需要确定最大值的范围,在本题中最小可能的最大值为 max(nums),最大可能的最大值为 sum(nums),我们可以用二分法查找最小的满足条件的最大值。对于最小的最大值 mid,我们可以用 DFS 进行搜索,每次搜索时尝试将一个元素加入到当前的子集中,如果当前子集的和不超过 mid,则将其加入到当前子集中,否则进行回溯操作,换一条路径进行搜索。
如果当前的搜索路径能够构建出 K 个不重叠的子集,则说明 mid 值的范围可以往左缩小,否则 mid 值的范围需要往右扩大。
时间复杂度为 O(2^n),其中 n 为数组的长度。限制时间复杂度,可以加入相应的剪枝。
from typing import List
class Solution:
def canSplit(self, nums: List[int], k: int, mid: int, used: List[bool], cur: int) -> bool:
if k == 1:
return True
if cur == mid:
return self.canSplit(nums, k-1, mid, used, 0)
for i in range(len(nums)):
if not used[i] and cur + nums[i] <= mid:
used[i] = True
if self.canSplit(nums, k, mid, used, cur+nums[i]):
return True
used[i] = False
return False
def splitArray(self, nums: List[int], k: int) -> int:
left, right = max(nums), sum(nums)
while left <= right:
mid = left + (right - left) // 2
if self.canSplit(nums, k, mid, [False]*len(nums), 0):
right = mid - 1
else:
left = mid + 1
return left