410. 分割数组的最大值

Hard

方法一(二分搜索)

思路

首先我们分析一下题目的意思,将数组分割到m个子数组,然后确保这些字数组的和的最小的最大值是多少。

可以确定的是最大值得范围一定是在[max(n), sum(n)]的区间范围当中。我们要在范围中找到一个目标值想到可以使用二分查找来求解。

以上,尝试写一下代码,AC!

代码

python3

class Solution:
  def splitArray(self, nums: List[int], m: int) -> int:
    def count(nums,target):
      s = 0
      cnt = 1 #不分割就是有一个
      for i,v in enumerate(nums):
        s += v
        if s > target:
          cnt += 1
          s = v
      return cnt

    i = max(nums)
    j = sum(nums)
    while i < j:
      mid = i+(j-i)//2
      if count(nums,mid) > m:
        i = mid + 1
      else:
        j = mid    
    return i

方法二(动态规划)(python3 TLE)

思路

这道题也可以考虑动态规划的方式求解

以上,尝试写一下代码,TLE

代码

python3

class Solution:
    def splitArray(self, nums: List[int], m: int) -> int:
      dp = [[math.inf for _ in range(len(nums))] for _ in range(m)]
      
      pre = 0
      presum = [0] * (len(nums) + 1)
      for i,v in enumerate(nums):
        dp[0][i] = pre + v
        presum[i+1] = dp[0][i]
        pre = dp[0][i]

      for k in range(1,m):
        for i in range(1,len(nums)):
          for j in range(1,i+1):
            dp[k][i] = min(dp[k][i], max(dp[k-1][j-1], presum[i+1] - presum[j]))

      return dp[m-1][-1]

据说用C++使用动态规划是可以AC的,未做尝试。