最大子序和
1.问题描述
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
2.求解
错误的动态规划
- 维护一个二维数组
sum[i][j]表示从i到j的和 - 初始化对角线数组
sum[i][i] = nums[i]; - 对于
sum[i][j] = sum[i][j - 1] + nums[j]
错误代码如下
public int maxSubArray(int[] nums) {
int len = nums.length;
int[][] sum = new int[len][len];
int max = nums[0];
for(int i = 0; i < len; i++){
sum[i][i] = nums[i];
if(nums[i] > max){
max = nums[i];
}
}
for(int i = 0; i < len - 1; i++){
for(int j = i + 1;j < len; j++){
sum[i][j] = sum[i][j - 1] + nums[j];
if(sum[i][j] > max){
max = sum[i][j];
}
}
}
return max;
}
- 执行超时,没有必要记录所有的值
真正的动态规划
- 对于
nums[i]只有两种情况,自己独自成为一段或者加入之前i-1的一段 - 如果我是
nums[i],我肯定希望前面传给我一个正数,给我一个负数把我变小,那我不如只要自己 - 使用变量pre来记录当前
i-1的值,使用变量ans记录每次的最大值 - 需要特别注意的是初始值,pre的初始值为0,但ans的初始值要设为数组的第一个数
代码如下
/*
*执行用时:1 ms, 在所有 Java 提交中击败了95.83% 的用户
* 内存消耗:38.3 MB, 在所有 Java 提交中击败了96.62% 的用户
* */
public int maxSubArray(int[] nums) {
int pre = 0,ans = nums[0];
for(int x : nums){
pre = Math.max(x,pre + x);
ans = Math.max(ans,pre);
}
return ans;
}
- 时间复杂度:O(n)
- 空间复杂度:O(1)

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
浙公网安备 33010602011771号