思路:
1.暴力法
2.动态规划:dp[i] 代表以元素 nums[i] 为结尾的连续子数组最大和,遍历dp找到最大值即可。
当 dp[i - 1] ≤0 时:执行 dp[i] = nums[i];
当 dp[i−1]>0 时:执行 dp[i] = dp[i-1] + nums[i];
此方法最后一个测试用例不能通过
public int maxSubArray(int[] nums) {
if (nums.length == 1) return nums[0];
int res = Integer.MIN_VALUE;
for (int i = 0; i < nums.length; i++) {
// 每次外循环,sum都重新置0
int sum = 0;
for (int j = i; j < nums.length; j++) {
sum += nums[j];
res = Math.max(res, sum);
}
}
return res;
}
class Solution {
public int maxSubArray(int[] nums) {
int[] dp = new int[nums.length];
dp[0] = nums[0];
for (int i = 1; i < nums.length; i++) {
if (dp[i - 1] > 0) {
dp[i] = dp[i - 1] + nums[i];
} else {
dp[i] = nums[i];
}
}
int max = Integer.MIN_VALUE;
for (int i = 0; i < dp.length; i++) {
if (dp[i] > max)
max = dp[i];
}
return max;
}
}
空间复杂度优化:由于dp[i] 只与 dp[i - 1] 和 nums[i] 有关系,因此可以将原数组 nums 用作 dp 列表,即直接在 nums 上修改即可。
if (nums[i - 1] > 0){
nums[i] += nums[i - 1];
}else {
nums[i] += 0;
}
public int maxSubArray(int[] nums) {
if (nums.length == 1) return nums[0];
int res = nums[0];
for (int i = 1; i < nums.length; i++) {
nums[i] += Math.max(nums[i - 1], 0);
res = Math.max(res, nums[i]);
}
return res;
}
public int maxSubArray4(int[] nums) {
int res = Integer.MIN_VALUE;
int sum = 0;
for (int i = 0; i < nums.length; i++) {
if (sum <= 0){
sum = nums[i];
}else {
sum += nums[i];
}
res = Math.max(sum, res);
}
return res;
}