回顾一下,前缀和数组 preSum
就是 nums
元素的累加和,preSum[i+1] - preSum[j]
其实就是子数组 nums[j..i]
之和(根据 preSum
数组的实现,索引 0 是占位符,所以 i
有一位索引偏移)。
那么反过来想,以 nums[i]
为结尾的最大子数组之和是多少?其实就是 preSum[i+1] - min(preSum[0..i])
。
所以,我们可以利用前缀和数组计算以每个元素结尾的子数组之和,进而得到和最大的子数组:
至此,前缀和解法也完成了。
简单总结下动态规划解法吧,虽然说状态转移方程确实有点玄学,但大部分还是有些规律可循的,跑不出那几个套路。像子数组、子序列这类问题,你就可以尝试定义 dp[i]
是以 nums[i]
为结尾的最大子数组和/最长递增子序列,因为这样定义更容易将 dp[i+1]
和 dp[i]
建立起联系,利用数学归纳法写出状态转移方程。