微软等数据结构与算法面试100题 第三题

第三题


题目:

输入一个整型数组,数组里面有正数也有负数,数组中连续的一个或者多个数组成一个子数组,每个子数组都有一个和。

求,所有子数组的和的最大值。要求时间复杂度为O(n)


分析:

本题是一个典型的使用动态规划算法的题目。

动态规划算法的使用基本要素是1、最优子结构(当问题的最优解包含了其子问题的最优解,成该问题具有最优子结构性质)

2、重叠子问题(也就是说如果使用递归算法自顶朝下求解问题时,每次产生的子问题并不是新问题,有一些子问题被反复计算多次)。

对于本题,要求计算和最大的一个子数组,对于是不是最优子结构的分析,假设数组为a[] (size=n),那么可以分割成为0-n-2和1-n-1两个子问题。

这两个子问题里面又都包含1-n-2子问题,可以使用递归算法,但是由于使用递归算法会造成大量的子问题的求解,因此使用动态规划算法。


动态规划算法

设SUM[i]为前i个元素中,包含第i个元素且和最大的连续数组,result为已找到的子数组中最大的,对于第i+1个元素,有两种选择,1.作为新子数组的

第一个元素,2.放入前面找到的数组。


sum[i+1] = max(a[i+1],sum[i]+a[i+1]);


本题若使用顺序求解算法 复杂度为O(n^2),递归求解算法复杂度为O(nlogn),动态规划算法复杂度为O(n)

顺序求解

递归求解

动态规划


代码:


#include<iostream>

using namespace std;

int maxSubArray(int *a, const int length)
{
	int maxSumSubArray = 0;

	int sum_i = 0;

	for(int i=0; i <length; i++)
	{
		sum_i = sum_i + a[i];

		if(sum_i < 0) sum_i = 0;
		else
		{
			if(sum_i > maxSumSubArray) maxSumSubArray = sum_i;
		}
	
	}

	//若是数组中的元素均为负值
	if(sum_i==0)
	{
		for(int i=0; i < length; i++)
		{
			if(a[i] > maxSumSubArray) maxSumSubArray = a[i];
		}
	}
	
	return maxSumSubArray;
	
}

int main()
{

	int a[10] = {1, 3, -3, -4 ,5 ,-2, 6, -1, 2, -6};
	int length = sizeof(a)/sizeof(int);

	cout<<maxSubArray(a,length);
	return 0;


}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值