笔记-最大子序列

   算法一:

<div>{CSDN:CODE:maxsubsum1.java}</div>


三次循环  O(N³)


   算法二:

public static int maxSubSum(int []a){
int maxSum = 0;
for(int i=0;i<a.length;){
int thisSum = 0;
for(int j=i;j<a.length;j++){
thisSum+=a[j];
if(thisSum>maxSum){
maxSum = thisSum;
}
}
}
return maxSum;
}

每次计算i到j的和
两次循环  O(N²)

   算法三:

public static int  maxSubSum(int []a){
int maxSum = 0,thisSum=0;
for(int i;i<a.length;i++){
thisSum+=a[i];
if(thisSum>maxSum){
maxSum = thisSum;
}else if(thisSum<0){
thisSum = 0;
}
}
return maxSum;
}

算法二的优化。对任意thisSum,若thisSum<0,就舍弃(即令thisSum=0)。否则继续加值必然变小。
一次循环 O(N)

   算法四:分治

public static int  maxSubSum(int []a){
return execute(a,0,a.length);
}
public int execute(int []a,int left,int right){
if(left==right){        //Base Case
if(a[left]>0)
return a[left];
else return 0;
}
int center = (left+right)/2;
int leftMaxSum = execute(int []a,int left,int center);
int rightMaxSum = execute(int []a,int center+1,right);
int maxLeftBorderSum = 0,thisLeftBorderSum = 0;
for(int i=center;i>=0;i--){
thisLeftBorderSum+=a[i];
if(thisLeftBorderSum>maxLeftBorderSum)
maxLeftBorderSum = thisLeftBorderSum;
}
int maxRightBorderSum = 0,thisRightBorderSum = 0;
for(int i=center+1;i<=a.length;i++){
thisRightBorderSum+=a[i];
if(thisRightBorderSum>maxRightBorderSum)
maxRightBorderSum = thisRightBorderSum;
}
return max3(leftMaxSum ,rightMaxSum ,maxLeftBorderSum+maxRightBorderSum);
}

最大子序列应该在左边,右边,过中点的两边各有。这三种情况之中。
每次求左边(右边)的最大子序列,又可以将其看作新的母序列。所以可用递归。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值