求最大子列和
求最大子列和
给定\(N\)个整数的序列\({A_1,A_2,\cdots,A_N}\),求函数\(f(i,j)=\max{\{0,\sum_{k=i}^jA_k\}}\)
算法一
int MaxSubseqSum1(int A[], int N) {/*三重嵌套循环,时间复杂度是O(N^3)*/
    int ThisSum, MaxSum = 0;
    int i, j, k;
    for (i = 0; i < N; i++) {/* i是子列左端位置*/
        for (j = i; j < N; j++) {/*j是子列右端位置*/
            ThisSum = 0; /*ThisSum是A[i]到A[j]的子列和*/
            for (k = i; k <= j; k++)
                ThisSum += A[k];
            if (ThisSum > MaxSum) /*如果刚得到的这个子列和更大*/
                MaxSum = ThisSum; /*则更新结果*/
        }
    }
    return MaxSum;
}
算法二
int MaxSubseqSum2(int A[], int N) {/*二重嵌套循环,时间复杂度是O(N^2)*/
    int ThisSum, MaxSum = 0;
    int i, j;
    for (i = 0; i < N; i++) {
        ThisSum = 0;
        for (j = i; j < N; j++) {
            ThisSum += A[j]; /*对于相同的i,不同的j,只要在j-1次循环的基础上累加1项即可*/
            if (ThisSum > MaxSum)
                MaxSum = ThisSum;
        }
    }
    return MaxSum;
}
算法三
int Max(int a,int b,int c){
    return a>b?(a>c?a:c):(b>c?b:c);
}
int MaxSubseqSum3(int A[],int left,int right){//分而治之法,时间复杂度为O(NlogN)
    int MaxLeftSum,MaxRightSum;//存放左右子问题的最大和
    int MaxLeftBorderSum,MaxRightBorderSum;//存放跨分界线的最大和
    int LeftBorderSum,RightBorderSum;//存放跨分界的子列和
    int center,i;//存放left和right的中线
    if(left==right){
        //当子列中只有一个数时停止递归
        if(A[left]>0)
            return A[left];
        else
            return 0;
    }
    //分而治之之一“分”
    center=(left+right)/2 ;//求left和right的中线
    //递归返回两边的子列最大和
    MaxLeftSum=MaxSubseqSum3(A,left,center);
    MaxRightSum=MaxSubseqSum3(A,center,right);
    //求跨分界线的最大子列和
    MaxLeftBorderSum=0;
    MaxRightBorderSum=0;
    for(i=center;i>=left;i--){
        //从中线向左扫描
        LeftBorderSum+=A[i];
        if(LeftBorderSum>MaxLeftBorderSum)
            MaxLeftBorderSum=LeftBorderSum;
    }
    MaxRightBorderSum=0;
    RightBorderSum=0;
    for(i=center+1;i<=right;i++){
        //从中线向右扫描
        RightBorderSum+=A[i];
        if(RightBorderSum>MaxRightBorderSum)
            MaxRightBorderSum=RightBorderSum;
    }
    return Max(MaxLeftSum,MaxRightSum,MaxLeftBorderSum+MaxRightBorderSum);
}
递归算法:
\(O(N)=O(\frac N2)+O(\frac N2)+cN=2O(\frac N2)+cN\\=2^kO(1)+ckN\)
其中\(N/2^k=1\),所以\(2^k=N\),\(k=\log_2{N}\),所以\(O(N)=NO(1)+cN\log_2N=O(N\log N)\)
算法四
int MaxSubseqSum4(int A[], int N) {//在线处理,时间复杂度为O(N)
    /*
     * “在线”的意思是指每输入一个数据就进行及时处理,在任何一个地方中止输入,算法都能正确给出当前的解
     */
    int ThisSum, MaxSum;
    int i;
    ThisSum = MaxSum = 0;
    for (i = 0; i < N; i++) {
        ThisSum += A[i];//向右累加
        if (ThisSum > MaxSum) //发现更大和则更新当前结果
            MaxSum = ThisSum;
        else if (ThisSum < 0) //如果当前子列和为负数
            ThisSum = 0; //则后面加上负数不可能是最大,所以抛弃该子列和
    }
    return MaxSum;
}
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号