Skip to content

Latest commit

 

History

History

1746.Maximum Subarray Sum After One Operation

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

English Version

题目描述

你有一个整数数组 nums。你只能将一个元素 nums[i] 替换为 nums[i] * nums[i]

返回替换后的最大子数组和。

 

示例 1:

输入:nums = [2,-1,-4,-3]
输出:17
解释:你可以把-4替换为16(-4*(-4)),使nums = [2,-1,16,-3]. 现在,最大子数组和为 2 + -1 + 16 = 17.

示例 2:

输入:nums = [1,-1,1,1,-1,-1,1]
输出:4
解释:你可以把第一个-1替换为1,使 nums = [1,1,1,1,-1,-1,1]. 现在,最大子数组和为 1 + 1 + 1 + 1 = 4.

 

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104

解法

方法一:动态规划

我们定义 $f[i]$ 表示以 $nums[i]$ 结尾,且没有进行替换的最大子数组和,另外定义 $g[i]$ 表示以 $nums[i]$ 结尾,且进行了替换的最大子数组和。那么有如下状态转移方程:

$$ \begin{aligned} f[i] &= \max(f[i - 1], 0) + nums[i] \\ g[i] &= \max(\max(f[i - 1], 0) + nums[i] \times nums[i], g[i - 1] + nums[i]) \end{aligned} $$

最终答案即为所有 $max(f[i], g[i])$ 的最大值。

由于 $f[i]$ 只与 $f[i - 1]$ 有关,因此我们可以只用两个变量来维护 $f[i]$$g[i]$ 的值,从而将空间复杂度降低到 $O(1)$

时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 $nums$ 的长度。

Python3

class Solution:
    def maxSumAfterOperation(self, nums: List[int]) -> int:
        f = g = 0
        ans = -inf
        for x in nums:
            ff = max(f, 0) + x
            gg = max(max(f, 0) + x * x, g + x)
            f, g = ff, gg
            ans = max(ans, f, g)
        return ans

Java

class Solution {
    public int maxSumAfterOperation(int[] nums) {
        int f = 0, g = 0;
        int ans = Integer.MIN_VALUE;
        for (int x : nums) {
            int ff = Math.max(f, 0) + x;
            int gg = Math.max(Math.max(f, 0) + x * x, g + x);
            f = ff;
            g = gg;
            ans = Math.max(ans, Math.max(f, g));
        }
        return ans;
    }
}

C++

class Solution {
public:
    int maxSumAfterOperation(vector<int>& nums) {
        int f = 0, g = 0;
        int ans = INT_MIN;
        for (int x : nums) {
            int ff = max(f, 0) + x;
            int gg = max(max(f, 0) + x * x, g + x);
            f = ff;
            g = gg;
            ans = max({ans, f, g});
        }
        return ans;
    }
};

Go

func maxSumAfterOperation(nums []int) int {
	var f, g int
	ans := -(1 << 30)
	for _, x := range nums {
		ff := max(f, 0) + x
		gg := max(max(f, 0)+x*x, g+x)
		f, g = ff, gg
		ans = max(ans, max(f, g))
	}
	return ans
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

...