**自己的学习小记录之最大子序列和**
今天看了最大子序列和和问题,感觉一个优质的算法是真的猛!不多说,记录一下四种求他们的方法。
**第一种**(就是举出每一个子序列)
代码如下
#include <stdio.h>
#include <stdlib.h>
int maxSubSum1(int a[],int n )
{
int i,j,k,sum,max=a[0];
for(i=0;i<n;i++)
for(j=i;j<n;j++)
{
sum=0;
for(k=i;k<=j;k++)
{
sum=sum+a[k];
}
//k这个循环是为了求子序列的和,个数为j-k+1,i是控制从第几个开始加,debug一个个去看慢慢看懂得哈哈,自己一开始也不太清楚。时间复杂度是n*n*n即O(n^3).
if(max<sum)
max=sum;
}
return max;
}
int main()
{
int a[]={-2, 11, -4, 13, -5, 2, -5, -3, 12, -9};
int n=10;
printf("%d",maxSubSum1(a,n));
return 0;
}
第二种(略微比第一种高级一点)
代码如下
#include <stdio.h>
#include <stdlib.h>
int maxSubSum1(int a[],int n )
{
int i,j,sum,max=a[0];
for(i=0;i<n;i++)
{
sum=0;
for(j=i;j<n;j++)
{
sum=sum+a[j];
if(max<sum)
max=sum;
}
//避免了求子序列每一次都从a[0]开始加,每加一次就比较一次,比上面那个好理解而且时间复杂度为n*n即O(n^2);
}
return max;
}
int main()
{
int a[]={-2, 11, -4, 13, -5, 2, -5, -3, 12, -9};
int n=10;
printf("%d",maxSubSum1(a,n));
return 0;
}
第三种(比较复杂,目前看懂了但感觉写还是有点困难,时间复杂度为O(NlogN))
代码比较长,应用了递归和分、治思想哈哈细致的我也不太清楚。主要思想还是看懂了。
主要思想如下:
4 -3 5 -2
-1 2 6 -2
如果这八个数找最大子序列把他均匀分为两部分,前面部分最大子序列是6,后面的是8,前面的所有和是4后面的所有和是7.比较6 8 4+7这三个数中的最大值就是最大子序列。前半部分后半部分又可以分为前半部分后半部分,就开始递归了。感觉自己现在水平不行,不是很能理解。
第四种(最简单也耗时短的一种时间复杂度为O(n^2))
代码如下
#include <stdio.h>
#include <stdlib.h>
int max(int a[],int n)
{
int i,sum=0,max=a[0];
for(i=0;i<n;i++)
{
sum=sum+a[i];//这句话就是再求子序列
if(max<sum)
max=sum;//把最大的子序列保存下来
else if(sum<0)
sum=0;//如果子序列小于零就要把它变为0,不然它会影响后面的子序列。
}
return max;
}
int main()
{
int a[]={-2, 11, -4, 13, -5, 2, -5, -3, 12, -9};
int n=10;
printf("%d",max(a,n));
return 0;
}
这些仅是自己学习记录,肯定是看了书看了其他博主的文章。望各位大佬多多指教!