子数组最大累加和《算法很美》

子数组最大累加和

分为两种方法

思路: 递推法:其实就是用了一次遍历所有的方式,遍历的时候,用了两个模块的方式去判断。

依次相加,如果>=0的就相加,如果<0就直接更新掉

   if (sumJ >=0) {//左子表的最大和正,继续向后累加
                sumJ += arr[j];
            }else{
                sumJ = arr[j];
            }

如果有大于max的就更新

 if (sumJ > max){
            max = sumJ;
        }

具体思路:

  1. 先将sumj = arr[0] ,max = sumj
  2. 遍历arr{2,3,1,-7,6,-4,2,12,-9,5}
  3. for (int j = 1; j< arr.length; j++)
  4. 当j为1的时候,此时sumJ(2) >=0,所以sumJ += arr[j](3);sumj=5
  5. 再判断 if (sumJ > max) max = sumJ(5);
  6. 当j为2的时候,此时sumJ(5) >=0,所以 sumJ += arr[j] (1) 则sumj=6
  7. 再判断 if (sumJ > max) max = sumJ(6);
  8. 当j为3的时候,此时sumJ(6)>0,所以sumJ+=arr[j] (-7) 则sumj=-1
  9. 再判断是否 if (sumJ > max) sumj<max
  10. 当j为4的时候,此时 sumj(-1)<0,所以丢弃前面的部分,直接sumJ = arr[j]; 此时sumj = 6
  11. 。。。。。。。
public class 子数组最大累加和 {
    static void findByForce(int[] arr){
        int maxSum = arr[0];

        for(int j = 0; j < arr.length; j++){
            int sum = arr[j]; //某个元素为子数组的第一个元素
            int maxOfJ = sum;

            for (int i=j+1;i<arr.length;i++){
                sum+=arr[i];//累加后续元素
                if (sum > maxOfJ){
                    maxOfJ = sum;
                }
            }
            if (maxOfJ>maxSum){
                maxSum = maxOfJ;
            }
        }
        System.out.println(maxSum);
    }

    //递推法 0(n)
    static int findByDp(int[] arr){
                int sumJ = arr[0]; //前J个元素的最大贡献
                int max = sumJ;
        int left = 0,right = 0;
        for (int j = 1; j< arr.length; j++){
            if (sumJ >=0) {//左子表的最大和正,继续向后累加
                sumJ += arr[j];
            }else{
                sumJ = arr[j];
                left=j;//丢弃前部分和的同时,更新left
            }

            if (sumJ > max){
                max = sumJ;
                right = j;//更新max的同时更新right
            }
        }
        // System.out.println(max=",left="+left+",right:"+right")
        return max;
    }


    public static void main(String[] args){
        int[] arr = {2,3,1,-7,6,-4,2,12,-9,5};
        long now = new Date().getTime();
        findByForce(arr);
        long next1 = new Date().getTime();
        System.out.println("暴力法,时间消耗"+(next1-now));

        findByDp(arr);
        long next2 = new Date().getTime();
        System.out.println("递推法:"+(next2-next1));
    }



}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值