最大子数组 III

这是一篇关于求解整数数组中,k个不重叠子数组最大和问题的文章。题目要求子数组元素位置连续,且探讨了二维动态规划的解决方案,通过压缩DP矩阵进行优化。
摘要由CSDN通过智能技术生成

题目链接:https://www.lintcode.com/problem/maximum-subarray-iii/description

 

给定一个整数数组和一个整数 k,找出 k 个不重叠子数组使得它们的和最大。每个子数组的数字在数组中的位置应该是连续的。

返回最大的和。

Example

样例1

输入: 
List = [1,2,3]
k = 1
输出: 6
说明: 1 + 2 + 3 = 6

样例2

输入:
List = [-1,4,-2,3,-2,3]
k = 2
输出: 8
说明: 4 + (3 + -2 + 3) = 8

Notice

子数组最少包含一个数

 

思路:二维DP

 

需要注意:一个dp数组记录当前最大值,一个dp数组记录全局最大值

状态定义:以当前数字作为结束点

注意:下标的大小关系一定要讨论清楚

 

class Solution:
    """
    @param nums: A list of integers
    @param k: An integer denote to find k non-overlapping subarrays
    @return: An integer denote the sum of max k non-overlapping subarrays
    """
    def maxSubArray(self, nums, k):
        # write your code here
        # 求子串最小值
        n = len(nums)
        if n<k:return None
        # dp[i][j]:表示以i结尾,含有j个子数组的最小值
        # 初始化
        local_dp = [[0]*(k+1) for i in range(n + 1)]
        gloabal_dp = [[0]*(k+1) for i in range(n + 1)]
        for i in range(1, n + 1):
            for j in range(1, k+1):
                if j<=i:
                    if j==i:
                        local_dp[i][j] = gloabal_dp[i - 1][j - 1] + nums[i - 1]
                        gloabal_dp[i][j] = local_dp[i][j]
                    if j<=i-1:
                        local_dp[i][j] = max(local_dp[i - 1][j]+nums[i-1], gloabal_dp[i - 1][j - 1] + nums[i - 1])
                        gloabal_dp[i][j]=max(gloabal_dp[i-1][j],local_dp[i][j])
                else:break
        return gloabal_dp[n][k]

优化:对二维DP矩阵压缩到一维度

class Solution:
    """
    @param nums: A list of integers
    @param k: An integer denote to find k non-overlapping subarrays
    @return: An integer denote the sum of max k non-overlapping subarrays
    """
    def maxSubArray(self, nums, k):
        # write your code here
        # 求子串最小值
        n = len(nums)
        if n<k:return None
        # dp[i][j]:表示以i结尾,含有j个子数组的最小值
        # 初始化
        local_dp = [0]*(k+1)
        gloabal_dp =[0]*(k+1)
        for i in range(1, n+1):
            for j in range(k,0,-1):
                if j<=i:
                    if j==i:
                        local_dp[j] = gloabal_dp[j - 1] + nums[i - 1]
                        gloabal_dp[j] = local_dp[j]
                    if j<=i-1:
                        local_dp[j] = max(local_dp[j]+nums[i-1], gloabal_dp[j - 1] + nums[i - 1])
                        gloabal_dp[j]=max(gloabal_dp[j],local_dp[j])
                else:continue
        return gloabal_dp[k]

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值