问题:
求一个序列的最大子段和即最大连续子序列之和,并可以实现单点修改。
刚拿到这个问题时,没想到用线段树,之前也做过类似的题目,先来分析一波,不用线段树的做法:
一、暴力求解: 时间复杂度最高 O(n3);
int maxsum(int *a,int n)
{
int sum,ma;
sum=ma= 0;
int i,j,k;
for(i=0;i<n;i++)
{
for(j = i;j<n;j++)
{
sum = 0;
for(k = i;k<=j;k++) sum+=a[k];
if(sum>ma) max=sum;
}
}
return ma;
}
二、暴力的改进版:时间复杂度 O(n2);
int maxsum(int *a,int n)
{
int sum,ma;
sum=ma=0;
int i,j;
for(i=0;i<n;i++)
{
sum=0;
for(j=i;j<n;j++)
{
sum += a[j];
if(sum>maxsum)
ma=sum;
}
}
return ma;
}
三、分治思想:
将序列划分为左右两部分,则最大子段和可能在三处出现:左半部、右半部以及跨越左右边界的部分,分别求出来 ,在比较大小。时间复杂度:O(nlogn)
int maxsum(int *a,int left,int right)
{
count++;
int sum,i,ret,center,leftmax,rightmax,left_max,right_max;
if(right==left) return a[left]>0?a[left]:0;
center=(left+right)/2;
leftmax=max(a,left,center