题目描述:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7,
2,
因此输出为该子数组的和18。
分析:
1、求一个数组的最大子数组和,如此序列1, -2, 3, 10, -4, 7, 2, -5,我想最最直观也是最野蛮的办法便是,三个for循环三层遍历,求出数组中每一个子数组的和,最终求出这些子数组的最大的一个值。
记Sum[i, …,
j]为数组A中第i个元素到第j个元素的和(其中0 <= i <= j < n),遍历所有可能的Sum[i, …,
j],那么时间复杂度为O(N^3):
实现代码:
View Code
1 int MaxSum(int *data,int n) 2 { 3 int iMax=-2147483648; 4 int iSum=0; 5 for (int i=0;i<n;i++) 6 { 7 for (int j=i;j<n;j++) 8 { 9 for (int k=i;k<=j;k++) 10 { 11 iSum+=data[k]; 12 } 13 if (iSum>iMax) 14 { 15 iMax=iSum; 16 } 17 iSum=0; 18 } 19 } 20 21 return iMax; 22 }
2.动态规划。DP解法的具体方程:设sum[i] 为前i个元素中,包含第i个元素且和最大的连续子数组,result 为已找到的子数组中和最大的。对第i+1个元素有两种选择:做为新子数组的第一个元素、放入前面找到的子数组。
sum[i+1] = max(a[i+1],
sum[i] + a[i+1])
result = max(result, sum[i])
时间复杂度为O(n)。
数组全为负数时,返回最大负数
1 int MaxSum2(int *data,int n) 2 { 3 int iMax=data[0]; 4 int iSum=0; 5 6 for (int i=0;i<n;i++) 7 { 8 if (iSum>=0) 9 { 10 iSum+=data[i]; 11 } 12 else 13 { 14 iSum=data[i]; 15 } 16 if (iSum>iMax) 17 { 18 iMax=iSum; 19 } 20 } 21 22 return iMax; 23 }
数组全为负数时,返回0
1 int MaxSum3(int *data,int n) 2 { 3 int iMax=0,iSum=0; 4 for (int i=0;i<n;i++) 5 { 6 iSum+=data[i]; 7 if (iSum>iMax) 8 { 9 iMax=iSum; 10 } 11 else if (iSum<0) 12 { 13 iSum=0; 14 } 15 16 } 17 return iMax; 18 19 }