最大相连子序列和

题目:最大的子序列和问题,给定(可能有负数)整数A1,A2,…,An,求∑Ak的最大值。

法一:最大相连子序列和的平方级算法

int maxSubSum(const std::vector<int>& a) {
	int maxSum = 0;
	for (int i = 0; i < a.size(); ++i) {
		int thisSum = 0;
		for (int j = i; j < a.size(); ++j) {
			thisSum += a[j];
			if (maxSum < thisSum)maxSum = thisSum;
		}
	}
	return maxSum;
}

法二:分治策略

相连最大子序列和的递归算法,找出生成[left…right]的子数组中的最大和,不保留具体的最佳序列。

int maxSubSum(const std::vector<int>&a, int left, int right) {
	if (left == right) { //基准情形,数组中只有一个元素时,大于0返回本身,小于0则返回0
		if (a[left] > 0)
			return a[left];
		else 
			return 0;
	}
	int mid = (left + right) / 2;
	int maxLeftSum = maxSubSum(a, left, mid);
	int maxRightSum = maxSubSum(a, mid+1, right);

	int maxLeftBorderSum = 0, maxRightBorderSum = 0; //以中点为起点的左右最大连续子序列和
	int leftBorderSum = 0, rightBorderSum = 0; //以中点为起点的左右相连子序列和
	for (int i = mid; i >= left; --i)
	{
		leftBorderSum += a[i];
		if (leftBorderSum > maxLeftBorderSum)
			maxLeftBorderSum = leftBorderSum;
	}

	for (int i = mid; i <= right; ++i) {
		rightBorderSum += a[i];
		if (rightBorderSum > maxRightBorderSum)
			maxRightBorderSum = rightBorderSum;
	}
	int temp = max(maxLeftSum, maxRightSum);
	return max(temp, maxLeftBorderSum + rightBorderSum);
}

法三:联机算法,线性时间最大相连子序列和算法

int maxSubSum3(const std::vector<int>&a)
{
	int maxSum = 0, thisSum = 0;
	for (int i = 0; i < a.size(); ++i) {
		thisSum += a[i];
		if (thisSum > maxSum)
			maxSum = thisSum;
		if (thisSum < 0)
			thisSum = 0;
	}
	return maxSum;
}

提示:联机算法(on-line algorithm),在任意时刻算法都能对已经读入的数据给出子序列问题的正确答案,这种仅需要常量空间并以线性时间运行的联机算法几乎是完美的算法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhugenmi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值