最大子序列问题
2017-03-29 15:32
323 查看
最大子序列问题就是求给出的序列中子序列最大值。
可以直接计算,不再具体描述,代码如下:
下面看一下分治思想:O(nlogn)
最大子序列出现的可能只有三种:
只出现在前半部分;
只出现在后半部分;
横跨了整个序列。
如下图序列:
算法实现如下:
把序列分成左右两部分,再继续划分:
求出左边两小部分最大子列:左边第一部分最大为4,第二部分为5
再求左边两小部分的跨越边界最大子序列:4-3+5=6
右边同理:
最后:
最后一种算法:在线处理,复杂度最低,为O(n)。如下图所示,前两个数相加为正,更新;前三个数相加为0不更新;前四个数相加为4,更新;前五个数为负,直接舍弃前五个数,因为负数相加只会使结果减小;然后算1+6=7;1+6-1=6
代码:
可以直接计算,不再具体描述,代码如下:
/*算法一,直接求出所有子序列,并比较,复杂度是O(n^3)*/ int maxsubseqsum1(int a[], int n) { int Thissum, maxsum = 0; int i, j, k; for (i = 0; i < n; i++) { for (j = i; j < n; j++) { Thissum = 0; for (k = i; k <= j; k++) Thissum += a[k]; if (Thissum > maxsum) maxsum = Thissum; } } return maxsum; } /*算法二 省去一个for循环 复杂度O(n^2)*/ int maxsubseqsum2(int a[], int n) { int Thissum, maxsum = 0; int i, j; for (i = 0; i < n; i++) { Thissum = 0; for (j = 0; j < n; j++) { Thissum += a[j]; if (Thissum > maxsum) maxsum = Thissum; } } return maxsum; }
下面看一下分治思想:O(nlogn)
最大子序列出现的可能只有三种:
只出现在前半部分;
只出现在后半部分;
横跨了整个序列。
如下图序列:
算法实现如下:
把序列分成左右两部分,再继续划分:
求出左边两小部分最大子列:左边第一部分最大为4,第二部分为5
再求左边两小部分的跨越边界最大子序列:4-3+5=6
右边同理:
最后:
最后一种算法:在线处理,复杂度最低,为O(n)。如下图所示,前两个数相加为正,更新;前三个数相加为0不更新;前四个数相加为4,更新;前五个数为负,直接舍弃前五个数,因为负数相加只会使结果减小;然后算1+6=7;1+6-1=6
代码:
/*算法四,在线处理*/ int maxsubseqsum3(int a[], int n) { int thissum, maxsum = 0; 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;//如果结果小于0,则不可能使后面和增大,所以要舍弃 } return maxsum; }