连续最大子段和(遍历,分治,递归)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;
}
发布了53 篇原创文章 · 获赞 46 · 访问量 7231

猜你喜欢

转载自blog.csdn.net/new_bee_01/article/details/101374299