LC.P53[最大子数组和]

方法一:动态规划

f[i]表示以 $i$ 结尾的连续子数组的和

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public int maxSubArray(int[] nums) {
int n = nums.length, ans = nums[0];
int[] f = new int[n];
f[0] = nums[0];
for (int i = 1; i < n; ++i) {
if (f[i - 1] > 0) f[i] = f[i - 1] + nums[i];
else f[i] = nums[i];
ans = Math.max(ans, f[i]);
}
return ans;
}
}
  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(n)$

方法二:优化空间

由于 $f[i]$ 只与 $f[i - 1]$ 有关系,因此可以只用一个变量 $f$ 来维护对于当前 $f[i]$ 的值是多少

1
2
3
4
5
6
7
8
9
10
class Solution {
public int maxSubArray(int[] nums) {
int ans = nums[0], f = nums[0];
for (int i = 1; i < nums.length; ++i) {
f = Math.max(f, 0) + nums[i];
ans = Math.max(ans, f);
}
return ans;
}
}
  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(1)$

方法三:前缀和

1
2
3
4
5
6
7
8
9
10
11
class Solution {
public int maxSubArray(int[] nums) {
int ans = Integer.MIN_VALUE, minPreSum = 0, preSum = 0;
for (int x : nums) {
preSum += x;
ans = Math.max(ans, preSum - minPreSum);
minPreSum = Math.min(minPreSum, preSum);
}
return ans;
}
}
  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(1)$