最大连续子序列和问题

第一次看《数据结构与算法分析——C语言描述》这本书的时候,被书中一上来就给的最大子序列和问题给直接镇住了。直观感觉就是好难,好牛逼。

问题描述:给定整数k1,k2,k3,...,kn,求从第i个数到第j个数的最大值。(如果所有整数均为负数,那么最大子序列和规定为0)

根据题目描述,最直接的算法就是穷举所有的从i到j的和,比较它们的大小,留下最大的那个和,就是我们所求的最大子序列和。

算法1:暴力穷举法

int MaxSubsequenceSum(const vector<int>& num, int n)
{
	int thissum, i, j, k, maxsum;
	maxsum = 0;
	for ( i = 0; i < n; i++)
	{
		for ( j = i; j < n; j++)
		{
			thissum = 0;
			for ( k = i; k <= j; k++)        //穷举计算从i到j个数的和
			{
				thissum += num[k];
			}
			if (thissum > maxsum)
			{
				maxsum = thissum;
			}
		}
	}
	return maxsum;
}

它的时间复杂度是O(n³),这个时间复杂度很大。不是一个好的算法。

算法2:简化求和

int MaxSubsequenceSum(vector<int> &num, int n)
{
	int thissum, i, j, maxsum;
	maxsum = 0;
	for ( i = 0; i < n; i++)
	{
		thissum = 0;
		for ( j = i; j < n; j++)
		{    //对上面算法计算和的过程进行了简化
			thissum += num[j];
			if (thissum > maxsum)
			{
				maxsum = thissum;
			}
		}
	}
	return maxsum;
}

它相对于算法1就快了许多,它的时间复杂度是O(n²)。当然我们说一般而言这种时间复杂度也不是一个好的算法。

算法3:联机算法(online algorithm)

int MaxSubsequenceSum(const vector<int>& num, int n)
{
	int thissum, maxsum, i;
	maxsum = thissum = 0;
	for ( i = 0; i < n; i++)
	{
		thissum += num[i];
		if (thissum > maxsum)
		{
			maxsum = thissum;
		}
		if (thissum < 0)		//规定如果是负数,则最大值为0;
		{
			thissum = 0;
		}
	}
	return maxsum;
}

这个算法的时间复杂度是O(n),贼快。

原文地址:https://www.cnblogs.com/zy666/p/10504294.html