最大子序列和-数据结构学习笔记1.3(基本概念)

来源:互联网 发布:保姆虐童什么心态知乎 编辑:程序博客网 时间:2024/05/19 16:48
给定一个整数序列,a0, a1, a2, …… , an(项可以为负数),求其中最大的子序列和。如果所有整数都是负数,那么最大子序列和为0;

例如:对于序列-2, 11, -4, 13, -5, –2。 所求的最大子序列和为20(从11到13,即从a1到a3)。


方法一:对所有的子序列求和,在其中找到最大的

int MaxSubseqSum1( int List[], int N ){int thissum,maxsum=0;int i,j,k;for(i=0;i<N;i++)//i为子列的左端for(j=0;j<N;j++){//j为子列的右端thissum=0;for(k=i;k<=j;k++){thissum+=List[k];if(thissum>maxsum)maxsum=thissum;}}return maxsum;}

方法二:对方法一的改善

int MaxSubseqSum2( int List[], int N ){int thissum,maxsum=0;int i,j,k;for(i=0;i<N;i++){//i为子列的左端thissum=0;for(j=0;j<N;j++)//j为子列的右端{thissum+=List[k];if(thissum>maxsum)maxsum=thissum;}}return maxsum;}
方法三:分而治之

 int Max3( int A, int B, int C )    { /* 返回3个整数中的最大值 */        return A > B ? A > C ? A : C : B > C ? B : C;    }         int DivideAndConquer( int List[], int left, int right )    { /* 分治法求List[left]到List[right]的最大子列和 */        int MaxLeftSum, MaxRightSum; /* 存放左右子问题的解 */        int MaxLeftBorderSum, MaxRightBorderSum; /*存放跨分界线的结果*/             int LeftBorderSum, RightBorderSum;        int center, i;             if( left == right )  { /* 递归的终止条件,子列只有1个数字 */            if( List[left] > 0 )  return List[left];            else return 0;        }             /* 下面是"分"的过程 */        center = ( left + right ) / 2; /* 找到中分点 */        /* 递归求得两边子列的最大和 */        MaxLeftSum = DivideAndConquer( List, left, center );        MaxRightSum = DivideAndConquer( List, center+1, right );             /* 下面求跨分界线的最大子列和 */        MaxLeftBorderSum = 0; LeftBorderSum = 0;        for( i=center; i>=left; i-- ) { /* 从中线向左扫描 */            LeftBorderSum += List[i];            if( LeftBorderSum > MaxLeftBorderSum )                MaxLeftBorderSum = LeftBorderSum;        } /* 左边扫描结束 */             MaxRightBorderSum = 0; RightBorderSum = 0;        for( i=center+1; i<=right; i++ ) { /* 从中线向右扫描 */            RightBorderSum += List[i];            if( RightBorderSum > MaxRightBorderSum )                MaxRightBorderSum = RightBorderSum;        } /* 右边扫描结束 */             /* 下面返回"治"的结果 */        return Max3( MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum );    }         int MaxSubseqSum3( int List[], int N )    { /* 保持与前2种算法相同的函数接口 */        return DivideAndConquer( List, 0, N-1 );    }
方法四:在线处理

int MaxSubseqSum4( int List[], int N ){int i,maxsum,thissum=0;for(i=0;i<N;i++){thissum+=List[i];//向右边累加if(thissum>maxsum){maxsum=thissum;//更新最大值}elseif(thissum<0){thissum=0;//负数不可能使后面的部分和增大抛弃之}return maxsum;}}
综合上面他们的时间复杂度分别为N^3 N^2 NlgN N但是算法的理解越来越难

0 0
原创粉丝点击