数据结构与算法分析 2.17 给出有效的算法(及其运行时间分析)

2.17 给出有效的算法(及其运行时间分析) 来:

a. 找出最小子序列和。

b. 找出最小的正子序列和。

c. 找出最大子序列乘积。

#include <iostream>
#include <string>
#include <vector>

using namespace std;
/*
*  最大子序列 ,复杂度: O(N^3) 
*/
int maxSubSum1(const vector<int> & a)
{
	int maxSum = 0;
	for (size_t i=0;i<a.size(); ++i)
		for (size_t j = i; j < a.size(); ++j)
		{
			int thisSum = 0;
			for (size_t k = i; k <= j; ++k)
				thisSum += a[k];
			if (thisSum > maxSum)
				maxSum = thisSum;
		}
	return maxSum;
}
/*
*  最大子序列 O(N^2)
*/
int maxSubSum2(const vector<int> & a)
{
	int maxSum = 0;
	for (size_t i = 0; i < a.size(); ++i)
	{
		int thisSum = 0;
		for (size_t j = i; j < a.size(); ++j)
		{
			thisSum += a[j];
			if (thisSum > maxSum)
				maxSum = thisSum;
		}
	}
	return maxSum;
}

/*
* 复杂度: O(N*logN)
*相连最大子序列和的递归算法 ,用到了分治的思想
*找出生成[left..right] 的子数组中的最大和
*不试图保留具体的最佳序列
*/

int maxSumRec(const vector<int> & a, int left, int right)
{
	if (left == right)
		if (a[left] > 0)
			return a[left];
		else
			return 0;
	int center = (left + right) / 2;
	int maxLeftSum = maxSumRec(a, left, center);
	int maxRightSum = maxSumRec(a, center + 1, right);

	int maxLeftBorderSum = 0, leftBorderSum = 0;
	for (int i = center; i >= left; --i)
	{
		leftBorderSum += a[i];
		if (leftBorderSum > maxLeftBorderSum)
			maxLeftBorderSum = leftBorderSum;
	}

	int maxRightBorderSum = 0, rightBorderSum = 0;
	for (int j = center + 1; j <= right; ++j)
	{
		rightBorderSum += a[j];
		if (rightBorderSum > maxRightBorderSum)
			maxRightBorderSum = rightBorderSum;
	}

	int maxBorderSum = maxLeftBorderSum + maxRightBorderSum;
	
	return maxLeftSum > maxRightSum ? (maxLeftSum > maxBorderSum ? maxLeftSum : maxBorderSum) :
									  (maxRightSum > maxBorderSum ? maxRightSum : maxBorderSum);
}

int maxSubSum3(const vector<int> & a)
{
	return maxSumRec(a, 0, a.size() - 1);
}



/*
*复杂度:O(N)
*最优求子序列最大和的方法
*/
int maxSubSum4(const vector<int> & a)
{
	int maxSum = 0, thisSum = 0;
	for (size_t j = 0; j < a.size(); ++j)
	{

		thisSum += a[j];

		if (thisSum > maxSum)
			maxSum = thisSum;
		/*任何最大子序列不可能从负数累加*/
		else if (thisSum < 0)   
			thisSum = 0;
	}
	return maxSum;
}


/*
* O(N)
* 最小的子序列和。
*/
int minSubSum(const vector<int> & a)
{
	int minSum = 0, thisSum = 0;
	for (size_t j = 0; j < a.size(); ++j)
	{

		thisSum += a[j];

		if (thisSum < minSum)
			minSum = thisSum;
		else if (thisSum > 0)
			thisSum = 0;
	}
	return minSum;
}

/*
*最小正子序列和
* O(N)
*/
int minPositiveSubSum(const vector<int> & a)
{
	int minSum = 0x7FFFFFFF, thisSum = 0;
	for (size_t j = 0; j < a.size(); ++j)
	{

		thisSum += a[j];

		if (thisSum < minSum && thisSum > 0)
			minSum = thisSum;
		else if (thisSum < 0)
			thisSum = 0;
	}
	return minSum;
}

/*
*最大正子序列乘积
* O(N)
*/
int maxPositiveSubMul(const vector<int> & a)
{
	int maxMul = 1, thisSum = 1;
	for (size_t j = 0; j < a.size(); ++j)
	{

		thisSum *= a[j];

		if (thisSum > maxMul && thisSum > 0)
			maxMul = thisSum;
		else if (thisSum < 0)
			thisSum = 1;
	}
	return maxMul;
}

int main()
{
	vector <int> souc = { 4,-3,5,-2,-1,2,6,-2,4,5,-8,6 };
	cout << "maxSubSum1:  " << maxSubSum1(souc) << endl;

	cout << "maxSubSum2:  " << maxSubSum2(souc) << endl;

	cout << "maxSubSum3:  " << maxSubSum3(souc) << endl;

	cout << "maxSubSum4:  " << maxSubSum4(souc) << endl;

	cout << "minSubSum:  " << minSubSum(souc) << endl;

	cout << "minPositiveSubSum:  " << minPositiveSubSum(souc) << endl;

	cout << "maxPositiveSubMul:  " << maxPositiveSubMul(souc) << endl;
	return 0;

}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值