最大连续子序列和问题
蛮力法求解:
时间复杂度为:o(n^3)
空间复杂度为:o(n)
蛮力法实现如下:
package algorithm;
public class Solution {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] nums = new int[] {-2,1,-3,4,-1,2,1,-5,4};
int max;
max=solve(nums);
System.out.println(max);
}
public static int solve(int[] nums) {
int maxLen=Integer.MIN_VALUE;
int sum=0;
for(int i=0;i<nums.length;i++) {
for(int j=i;j<nums.length;j++) {
sum=sumOfSucArray(nums,i,j);
maxLen=Math.max(sum, maxLen);
}
}
return maxLen;
}
//求区间连续的序列和
public static int sumOfSucArray(int[] nums,int i,int j) {
int sum=0;
for(int k=i;k<=j;k++) {
sum+=nums[k];
}
return sum;
}
}
运行结果如下:
动态规划求解:
分析:
第1步:定义状态
一个连续子数组一定要以一个数作为结尾,那么可以将状态定义成如下:
dp[i]:表示以nums[i]结尾的连续子数组的最大和。
时间复杂度:o(n)
空间复杂度:o(n)
package algorithm;
public class Solution {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] nums = new int[] {-2,1,-3,4,-1,2,1,-5,4};
int max;
max=solve(nums);
System.out.println(max);
}
public static int solve(int[] nums) {
int[] dp = new int[nums.length];
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 maxLen=Integer.MIN_VALUE;
for(int i=0;i<nums.length;i++) {
maxLen=Math.max(maxLen, dp[i]);
}
return maxLen;
}
}
优化空间:
package algorithm;
public class Solution {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] nums = new int[] { -2, 1, -3, 4, -1, 2, 1, -5, 4 };
int max;
max = solve(nums);
System.out.println(max);
}
public static int solve(int[] nums) {
if (nums.length == 0)
return 0;
int pre = nums[0];
// 记录上一个状态,与dp数组意义相同
int res = pre;
for (int i = 0; i < nums.length; i++) {
pre = Math.max(nums[i], pre + nums[i]);
// 更新状态
res = Math.max(pre, res);
// res记录最大连续子序列和
}
return res;
}
}