题目:输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。
编程之美上的题,题目的详细分析看书去。这里,主要提一下需要注意的地方和经常遇到的几种变形。
需要关注的就是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