求数组的子数组之和的最大值

题目:输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。

编程之美上的题,题目的详细分析看书去。这里,主要提一下需要注意的地方和经常遇到的几种变形。


需要关注的就是A[i], A[i] + Start[i+1] , All[i+1]这3个数的大小。

公式:All[i] = max(A[i], A[i] + Start[i+1] , All[i+1]);

看起来很简单,但是,请看清楚上面对Start和All的定义。均是向后拓展。

书中的代码:

int max(int x, int y)
{
	return (x > y) ? x : y;
}
int MaxSumofSubArray(int *a, int n)
{
	start[n-1] = a[n-1];
	all[n-1] = a[n-1];
	for (int i = n-2; i >= 0; i--)
	{
		start[i] = max(a[i],a[i]+start[i+1]);
		all[i] = max(start[i],all[i+1]);
	}
	return all[0];
}
若函数这样写呢,横线处怎么写?

int MaxSumofSubArray1(int *a, int n)
{
	start[0] = a[0];
	all[0] = a[0];
	for (int i = 1; i < n; i++)
	{
		//_____________
		//_____________
	}
	return _______; 
}
则要注意Start[i]表示的是(A[0],...,A[i])包含A[i]的和最大的子数组。All[i]表示的是(A[0],...,A[i])的最大子数组的和。
下面给出各种写法:

#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 100;
int start[maxn],all[maxn];
int max(int x, int y)
{
	return (x > y) ? x : y;
}
int MaxSumofSubArray(int *a, int n)
{
	start[n-1] = a[n-1];
	all[n-1] = a[n-1];
	for (int i = n-2; i >= 0; i--)
	{
		start[i] = max(a[i],a[i]+start[i+1]);
		all[i] = max(start[i],all[i+1]);
	}
	return all[0];
}

int MaxSum(int *a, int n)
{
	int nStart = a[n-1];
	int nAll = a[n-1];
	for (int i = n-2; i >= 0;i--)
	{
		nStart = max(a[i], nStart + a[i]);
		nAll = max(nStart, nAll);
	}
	return nAll;
}
int MaxSum2(int *a, int n)
{
	int nStart = a[n-1];
	int nAll = a[n-1];
	for (int i = n-2; i >= 0; i--)
	{
		if (nStart < 0)
			nStart = 0;
		nStart += a[i];
		if (nStart > nAll)
		{
			nAll = nStart;
		}
	}
	return nAll;
}
int MaxSum1(int *a, int n)
{
	int nStart = a[0];
	int nAll = a[0];
	for (int i = 1; i < n; i++)
	{
		nStart = max(a[i], nStart + a[i]);
		nAll = max(nStart, nAll);
	}
	return nAll;
}
int MaxSumofSubArray1(int *a, int n)
{
	//注意扩展的顺序不一样
	start[0] = a[0];
	all[0] = a[0];
	for (int i = 1; i < n; i++)
	{
		start[i] = max(a[i],start[i-1]+a[i]);
		all[i] = max(start[i],all[i-1]);
	}
	return all[n-1]; //应返回all[n-1]
}
int main()
{
	int a[6] = {1,-2,3,5,-3,2};
	int b[6] = {0,-2,3,5,-1,2};
	int c[6] = {-9,-2,-3,-5,-1,-3};
	int res = MaxSumofSubArray(c,6);
	printf("%d\n",res);
	int r1 = MaxSum1(a,6);
	printf("%d\n",r1);
	int r2 = MaxSum2(c,6);
	printf("%d\n",r2);
	int r3 = MaxSumofSubArray1(a,6);
	printf("%d\n",r3);
	return 0;
}
顺便提下,这是腾讯2013校招的笔试题。


完整笔试题信息查看:http://blog.youkuaiyun.com/arcsinsin/article/details/12261847

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值