LeetCode 53. Maximum Subarray
题目描述
给定一个整数数组 nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
样例
输入: [-2,1,-3,4,-1,2,1-5,4],
输出:6
进阶
如果你已经实现复杂度为 O ( n ) O(n) O(n)的解法,尝试使用更精妙的分治法求解。
算法1
(动态规划)O(n)
1.设
f
(
i
)
f(i)
f(i)表示以第
i
i
i个数字为结尾的最大连续子序列的总和是多少。
2.初始化
f
(
0
)
f(0)
f(0) = nums[0]。
3.转移方程
f
(
i
)
=
m
a
x
(
f
(
i
−
1
)
+
n
u
m
s
[
i
]
,
n
u
m
s
[
i
]
)
f(i) = max(f(i-1)+nums[i],nums[i])
f(i)=max(f(i−1)+nums[i],nums[i])。意味当前有两种决策,一种是将第i个数字和前面的数字拼接起来;另一种是第i个数字单独作为一个新的子序列开始。
4.最终答案为
a
n
s
=
m
a
x
(
f
(
k
)
)
,
0
<
=
k
<
n
ans = max(f(k)),0<=k<n
ans=max(f(k)),0<=k<n。
时间复杂度
状态数为 O ( n ) O(n) O(n),转移时间为 O ( 1 ) O(1) O(1),故总时间复杂度为 O ( n ) O(n) O(n)。
空间复杂度
需要 O ( n ) O(n) O(n)的空间储存状态
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int n = nums.size(), ans;
vector<int> f(n);
f[0] = nums[0];
ans = f[0];
for (int i = 1; i < n; i++) {
f[i] = max(f[i - 1] + nums[i], nums[i]);
ans = max(ans, f[i]);
}
return ans;
}
};