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

题目要求:一个有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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值