📜  最大和子数组最多删除一个元素(1)

📅  最后修改于: 2023-12-03 15:26:25.660000             🧑  作者: Mango

最大和子数组最多删除一个元素

给定一个整数数组,你需要找到一个连续子数组,如果你只能在这个子数组中删除一个元素,那么剩余元素相加之和最大。

示例

输入:

[1,-2,3,-2]

输出:

4

解释:

在第二个数字 -2 前面或者后面删除一个1 可以获得最大和的子数组[3] 的和 3。所以答案是 3 + 1 = 4。
解法

本题通过分别考虑子串不包含数组中任一元素和子串包含一个元素两种情况来解决。

首先,我们假设子串不包含数组中任一元素,那么问题就转化为了寻找最大连续子串。这个问题可以通过动态规划或者 Kadane 算法解决。这里我们采用 Kadane 算法,时间复杂度为 $O(n)$。

然后,我们继续考虑子串包含一个元素的情况。对于每个元素,我们分别计算其左边最大连续子串和右边最大连续子串,然后将这两个和相加,即可得到以该元素为分界元素的最大和子数组。其中,左边最大连续子串和右边最大连续子串的计算也同样可以使用 Kadane 算法。当然,在计算右边最大连续子串时,需要倒序遍历数组。最后,遍历数组中的每个元素,找到其中的最大值即可。

时间复杂度为 $O(n)$。

代码
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        def maxSub(nums):
            maxSum = nums[0]
            curSum = 0
            for num in nums:
                curSum += num
                maxSum = max(maxSum, curSum)
                curSum = max(curSum, 0)
            return maxSum

        n = len(nums)
        if n == 1:
            return nums[0]
        left_sums = [0] * n
        left_sums[0] = nums[0]
        for i in range(1, n):
            left_sums[i] = max(nums[i], left_sums[i-1]+nums[i])
        right_sums = [0] * n
        right_sums[n-1] = nums[n-1]
        for i in range(n-2, -1, -1):
            right_sums[i] = max(nums[i], right_sums[i+1]+nums[i])
        max_sum = max(maxSub(nums), max(left_sums[:-1] + [0]) + max(right_sums[1:] + [0]))
        return max_sum

参考: