LEETCODE ALGORITHM:53. Maximum Subarray
题目
Given an integer array nums, find the contiguous
subarray (containing at least one number) which has the largest sum and
return its sum.
Example:
1 | Input: \[-2,1,-3,4,-1,2,1,-5,4\], |
Follow up:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
题解
dp
\[ 转移方程:f(i)=max\{f(i-1)+a_i,a_i\} \]
1 | class Solution { |
分治
对于一个区间 [l, r][l,r],我们可以维护四个量:
lSum表示 [l, r][l,r] 内以 ll 为左端点的最大子段和rSum表示 [l, r][l,r] 内以 rr 为右端点的最大子段和mSum表示 [l, r][l,r] 内的最大子段和iSum表示 [l, r][l,r] 的区间和以下简称 [l, m][l,m] 为 [l, r][l,r] 的「左子区间」,\[m + 1, r\]\[m+1,r\] 为 \[l, r\]\[l,r\] 的「右子区间」。我们考虑如何维护这些量呢(如何通过左右子区间的信息合并得到 [l, r][l,r] 的信息)?对于长度为 11 的区间 [i, i][i,i],四个量的值都和 a_i*a**i* 相等。对于长度大于 11 的区间:
- 首先最好维护的是
iSum,区间 [l, r][l,r] 的iSum就等于「左子区间」的iSum加上「右子区间」的iSum。- 对于 [l, r][l,r] 的
lSum,存在两种可能,它要么等于「左子区间」的lSum,要么等于「左子区间」的iSum加上「右子区间」的lSum,二者取大。- 对于 [l, r][l,r] 的
rSum,同理,它要么等于「右子区间」的rSum,要么等于「右子区间」的iSum加上「左子区间」的rSum,二者取大。- 当计算好上面的三个量之后,就很好计算 [l, r][l,r] 的
mSum了。我们可以考虑 [l, r][l,r] 的mSum对应的区间是否跨越 mm——它可能不跨越 mm,也就是说 [l, r][l,r] 的mSum可能是「左子区间」的mSum和 「右子区间」的mSum中的一个;它也可能跨越 mm,可能是「左子区间」的rSum和 「右子区间」的lSum求和。三者取大。
1 | class Solution { |
分治参考
https://leetcode-cn.com/problems/maximum-subarray/solution/zui-da-zi-xu-he-by-leetcode-solution/