求数组的子数组之和的最大值
问题描述:一个有N个整数元素的一维数组(A[0],A[1]......A[n-2],A[n-1]),这个数组当然有很多子数组,那么子数组之和的最大值是什么呢?
分析:题目说的子数组,是连续的;数组元素可以使负数和零;只需要求和,不需要返回子数组的具体位置。
举例如下:
【1,-2,3,5,-3,2】应返回:8;
【0,-2,3,5,-1,2】应返回:9;
【-9,-2,-3,-5,-3】应返回-2;
java代码如下(已通过测试):
public class MaxSumVersion {
static int arr[] = {1,-2,3,5,-3,2};
static int length = arr.length;
static int[] Start = new int[length-1];
static int[] All = new int[length-1];
public static void main(String[] args) {
// maxSumMethod1(arr,length);
// maxSumMethod2(arr,length);
maxSumMethod3(arr,length-1);
}
public static void maxSumMethod1(int[] arr,int n){
int maxiSum = -999;
int sum = 0;
for(int i = 0;i < n;i++){
for(int j = i;j < n;j++){
for(int k = i;k <= j;k++){
sum += arr[k];
//System.out.println("maxiSum : " + i + ":" + j + ":" + k + ":" + + sum);
if(sum > maxiSum){
maxiSum = sum;
}
}
sum = 0;
}
}
System.out.println("maxSumMethod1 : " + maxiSum);
}
public static void maxSumMethod2(int[] arr,int n){
int maxiSum = -999;
int sum = 0;
for(int i = 0;i < n;i++){
for(int j = i;j < n;j++){
sum += arr[j];
if(sum > maxiSum){
maxiSum = sum;
}
//System.out.println("maxiSum : " + i + ":" + j + " " + sum);
}
sum = 0;
}
System.out.println("maxSumMethod2 : " + maxiSum);
}
// 返回x,y两者中的较大值
private static int max(int x, int y){
return (x > y) ? x : y;
}
public static void maxSumMethod3(int[] arr, int n)
{
Start[n - 1] = arr[n - 1];
All[n - 1] = arr[n - 1];
// 从数组末尾往前遍历,直到数组首
for(int i = n - 2; i >= 0; i--)
{
Start[i] = max(arr[i], arr[i] + Start[i + 1]);
All[i] = max(Start[i], All[i + 1]);
}
// 遍历完数组,All[0]中存放着结果
System.out.println("maxSumMethod3 : " + All[0]);
}
}
static int arr[] = {1,-2,3,5,-3,2};
static int length = arr.length;
static int[] Start = new int[length-1];
static int[] All = new int[length-1];
public static void main(String[] args) {
// maxSumMethod1(arr,length);
// maxSumMethod2(arr,length);
maxSumMethod3(arr,length-1);
}
public static void maxSumMethod1(int[] arr,int n){
int maxiSum = -999;
int sum = 0;
for(int i = 0;i < n;i++){
for(int j = i;j < n;j++){
for(int k = i;k <= j;k++){
sum += arr[k];
//System.out.println("maxiSum : " + i + ":" + j + ":" + k + ":" + + sum);
if(sum > maxiSum){
maxiSum = sum;
}
}
sum = 0;
}
}
System.out.println("maxSumMethod1 : " + maxiSum);
}
public static void maxSumMethod2(int[] arr,int n){
int maxiSum = -999;
int sum = 0;
for(int i = 0;i < n;i++){
for(int j = i;j < n;j++){
sum += arr[j];
if(sum > maxiSum){
maxiSum = sum;
}
//System.out.println("maxiSum : " + i + ":" + j + " " + sum);
}
sum = 0;
}
System.out.println("maxSumMethod2 : " + maxiSum);
}
// 返回x,y两者中的较大值
private static int max(int x, int y){
return (x > y) ? x : y;
}
public static void maxSumMethod3(int[] arr, int n)
{
Start[n - 1] = arr[n - 1];
All[n - 1] = arr[n - 1];
// 从数组末尾往前遍历,直到数组首
for(int i = n - 2; i >= 0; i--)
{
Start[i] = max(arr[i], arr[i] + Start[i + 1]);
All[i] = max(Start[i], All[i + 1]);
}
// 遍历完数组,All[0]中存放着结果
System.out.println("maxSumMethod3 : " + All[0]);
}
}
复杂度排序:
method1 > method2 > method3;
以上代码在原文基础上略有改编,原文用的是c++,而且sum没有归零。