求数组的子数组之和的最大值(编程之美)

来源:互联网 发布:淘宝最迟几天发货 编辑:程序博客网 时间:2024/05/17 02:54

题目要求:一个有N个整数元素的一维数组(A[0],A[1],···,A[n-2]、A[n-1]),这个数组当然有很多子数组,那么子数组中和最大值是多少呢?
1、子数组是连续的
2、求子数组的和,不用求子数组的具体位置
3、数组的元素时整数,所以数组可能包含有正整数、零、负整数

解法一:暴力解法,从数组的第0位开始遍历数组查找出sum[i,…,j]表示数组从第i位到底j位的和。

/** 求数组的子数组之和的最大值*/public static int MaxSum(int[] nums){    int n = nums.length;    int sum = 0;    int max = Integer.MIN_VALUE;    //这里的时间复杂度为N的三次幂//  for(int i = 0; i < n; i++){//      for(int j = i; j < n; j++){//          for(int k = i; k <= j; k++){//              sum += nums[k];//          }//          if(sum > max){//              max = sum;//          }            //每次计算完一次sum[i,...,j]的和之后,都需要将sum清零//          sum = 0;//      }//  }    //给出一个简单的优化,使得算法的时间复杂度为N的二次幂    for(int i = 0; i < n; i++){        for(int j = i; j < n; j++){            sum += nums[j];            if(sum > max)                max = sum;            }            //每次计算完一次sum[i,...,j]的和之后,都需要将sum清零            sum = 0;    }    return max;}

解法二:采用分治的思想,将时间复杂度降到〖N*log〗_2⁡N。考虑数组的第一个元素A[0],以及最大的一段数组(A[i],….,A[j])跟A[0]之间的关系:
1、当0=i=j时,元素A[0]本身构成和最大的一段
2、当0=i

public static int MaxSum_2(int[] nums){    int n = nums.length;    int all = nums[n-1];    int start = nums[n-1];    for(int i = n-2; i >= 0; i--){        start = max(nums[i],nums[i] + start);        all = max(start,all);    }    return all;}public static int MaxSum_1(int[] nums){    int n = nums.length;    int[] all = new int[n];    int[] start = new int[n];    start[n-1] = nums[n-1];    all[n-1] = nums[n-1];    for(int i = n-2; i >= 0; i--){        start[i] = max(nums[i],nums[i] + start[i+1]);        all[i] = max(start[i],all[i+1]);    }    return all[0];}public static int max(int x,int y){    return (x > y) ? x : y;}
阅读全文
0 0
原创粉丝点击