求最大子列和问题

求最大子列和问题

题目

给定K个整数组成的序列{ N​1, N2, …, N​K},“连续子列”被定义为{ N​i, Ni+1, …, Nj },其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。

第一种方法(最不好)

在此方法中用了三个循环,第一层是子列左端,第二层是子列右端,里层为子列的求和。T(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; /*则更新结果*/
	}
}

第二种方法

其实就是把最里层的循环去掉

int ThisSum , MaxSum = 0;
int i,j,k;
for( i = 0; i < N; i++) /*i是子列左端位置*/
{
	ThisSum = 0; /*ThisSum是从A[i]到A[j]的子列和*/
	for( j = i; j < N; j++) /* J是子列右端位置*/
	{
		ThisSum += A[j];/*对于相同的i,不同的j,只要在j-i次循环的基础上累加1项即可*/
		if( ThisSum > MaxSum ) /*如果刚得到的这个子列和更大*/
			MaxSum = ThisSum; /*则更新结果*/
	}
}

第三种:分治法

第四种:在线处理(最好)

	int n,m,maxsum=0,zisum=0;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>m;
		
		zisum += m;  /*向右累加*/
		if(zisum>maxsum)
		{
			maxsum=zisum;  /* 发现了更大的子列则更新现在的结果*/
		}
		else if(zisum<0)  /* 若当前子列和为负*/
		{
			zisum=0;  /* 不可能使后面的部分和增大,抛弃之*/
		}
	}
	cout<<maxsum;

时间复杂度

求最大子列和问题_第1张图片

你可能感兴趣的:(求最大子列和问题)