LeetCode #410: Split Array Largest Sum

Problem Statement

(Source) Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays.

Note:
Given m satisfies the following constraint: 1 ≤ m ≤ length(nums) ≤ 14,000.

Examples:

Input:
nums = [7,2,5,10,8]
m = 2

Output:
18

Explanation:
There are four ways to split nums into two subarrays.
The best way is to split it into [7,2,5] and [10,8],
where the largest sum among the two subarrays is only 18.

Tags: Binary Search, Dynamic Programming.

Solution 1 - Dynamic Programming

首先想到的是用动态规划来解决。用dp[i][j] (zero-based indices)表示子问题:“把nums[0 : i + 1]划分成j + 1个连续非空子数组时,使得这些子数组分别的和的最大值最小化”的解。

class Solution(object):
    def splitArray(self, nums, m):
        """
        :type nums: List[int]
        :type m: int
        :rtype: int
        """
        n = len(nums)
        prefix_sum = [x for x in nums]
        for i in xrange(1, n):
            prefix_sum[i] += prefix_sum[i-1]
        dp = [[0 for j in xrange(m)] for i in xrange(n)]
        for i in xrange(n):
            dp[i][0] = prefix_sum[i]
        for j in xrange(1, m):
            for i in xrange(n):
                dp[i][j] = float('inf')
                for k in xrange(j - 1, i + 1):
                    dp[i][j] = min(dp[i][j], max(dp[k][j-1], prefix_sum[i] - prefix_sum[k]))
        return dp[-1][-1]

But, TLE…(:

class Solution(object):
    def splitArray(self, nums, m):
        """
        :type nums: List[int]
        :type m: int
        :rtype: int
        """
        l, r = max(nums), sum(nums)
        while l <= r:
            mid = (l + r) >> 1
            if self.validate(nums, m, mid):
                r = mid - 1
            else:
                l = mid + 1
        return l

    def validate(self, nums, m, res):
        """Validate if nums can be splited into m non-empty continuous 
        subarrays with the largest sum among these m subarrays no more 
        than res

        :type nums: List[int]
        :type m: int
        :type res: int
        :rtype: boolean
        """
        count, total = 1, 0
        for i in xrange(len(nums)):
            total += nums[i]
            if total > res:
                total = nums[i]
                count += 1
            if count > m:
                return False
        return True

References:
(1) https://discuss.leetcode.com/topic/61324/clear-explanation-8ms-binary-search-java

Complexity Analysis: TODO

你可能感兴趣的:(算法,LeetCode,动态规划,二分搜索)