连续最大子段和(遍历,分治,递归)C++

连续最大子段和问题

给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。

方法一 : 遍历 O(n2)

最简单的方法, 但时间复杂度太高

int FindGreatestSumOfSubArrayWay1(vector<int> data)
{
	int sum = 0;
	int thisSum = 0;
	for (size_t i = 0; i < data.size(); i++)
	{
		thisSum = 0;
		for (size_t j = i; j < data.size(); j++)
		{
			thisSum += data[j];
			if (thisSum > sum)
			{
				sum = thisSum;
			}
		}
	}
	return sum;
}

方法二 : 分治法 O(nlogn)

最常见的方法, 代码略微复杂

int dealGreatestSum(vector<int> &array, int begin, int end)
{
	if (begin == end)
	{
		return array[begin];
	}

	int mid = (begin + end) / 2;
	int leftmax = dealGreatestSum(array, begin, mid);
	int rightmax = dealGreatestSum(array, mid + 1, end);

	int crossmax = 0;

	int i;
	int sum = 0;
	int tmpmax = array[mid];
	for (i = mid; i >= begin; i--)
	{
		sum += array[i];
		if (sum > tmpmax)
		{
			tmpmax = sum;
		}
	}
	crossmax += tmpmax;

	sum = 0;
	tmpmax = array[mid + 1];
	for (i = mid + 1; i <= end; i++)
	{
		sum += array[i];
		if (sum > tmpmax)
		{
			tmpmax = sum;
		}
	}
	crossmax += tmpmax;

	return max(max(leftmax, rightmax), crossmax);
}

//入口
int FindGreatestSumOfSubArrayWay2(vector<int> array)
{
	return dealGreatestSum(array, 0, array.size() - 1);
}

方法三 : 入门级动态规划 O(n)

最快的方法

int FindGreatestSumOfSubArrayWay3(vector<int> data)
{
	int maxSum = data[0];
	int tmp = data[0];

	for (size_t i = 1; i < data.size(); i++)
	{
		if (tmp >= 0)
		{
			tmp += data[i];
		}
		else
		{
			tmp = data[i];
		}

		if (maxSum < tmp)
		{
			maxSum = tmp;
		}
	}
	return maxSum;
}

主函数及头文件:

#include <iostream>
#include <cstdlib>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
	int array[8] = { 1, 2, -2, 1, -2 , 1, 3, -5};

	vector<int> data(array, array + 8);

//	cout << FindGreatestSumOfSubArrayWay1(data);
//	cout << FindGreatestSumOfSubArrayWay2(data);
//	cout << FindGreatestSumOfSubArrayWay3(data);
	system("pause");
	return 0;
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值