一.O(n^3)
列举起点与终点然后求每个子序列的和
for(int i=0;i<n;i++) cin>>a[i];
int left,right;
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
long long sum=0;
for(int k=i,k<=j;k++){
sum+=a[k];
}
if(sum>maxx){
left=i,right=j,maxx=sum;
}
}
}
二.O(n^2)
第一层循环列举起点,第二层用来求和,
for(int i=0;i<n;i++) cin>>a[i];
int maxx=0,left,right;
for(int i=0;i<n;i++){
long long sum=0;
for(int j=i;j<n;j++){
sum+=a[j];
if(sum>maxx){
maxx=sum;
left=i,right=j
}
}
}
三.O(n)
思想就是从第一个数开始相加,如果和小于零了,就舍弃该段子序列,让当前的和等于0;如果大于maxx(记录最大子序列和)就让maxx=当前的和并更新左右点(让left=m(记录起点,让right=i),值得注意得是如果小于零我们必须也要让m进行更新,让它等于和小于零的那段子序列的尾端+1,因为我们要舍去当前这段小于0的子序列,那么下一个序列的开始则为当前的i+1,特判一下就是如果m>n,那么m=n.
for(int i=1;i<=n;i++) cin>>a[i];
int left,right,maxx=INT_MIN,sum=0,m=1;//左边界,右边界,子序列最大值,当前和,记录起点。
for(int i=1;i<=n;i++){
sum+=a[i];
if(sum>maxx){
maxx=sum;
left=m,right=i;
}
if(sum<0){
sum=0;
m=i+1;
if(m>n) m=n;
}
}
标签:maxx,right,最大,求和,sum,int,序列,left
From: https://blog.51cto.com/u_16085557/6715836