Hot-Leecode 2:最大子数组和(53)

今天是leecode的第二题,随机来一道题目:最大子数组和,这道题在做完后我还举一反三多加了两个问题,加深了一下对代码的感觉。

题目感悟

1.这题让我知道了动态规划;

2.动态规划理解:它是将问题分解为更小的子问题

3.而且这道题,它并没有要你输出子数组出来,只是让你输出连续子数组的和

第一次代码

class Solution {
    public int maxSubArray(int[] nums) {
        if(nums.length==0 || nums==null){
            System.out.println("数组为空");
        }
        int currentMax=nums[0];//记录当前子数组最大和
        int allMax=nums[0];//记录整个数组最大和

        //对于当前元素,要么加入到子数组,要么从这个元素开始计和
        //如果当前元素,加上子数组,发现还没有当前元素大,那么就从当前元素开始开始算子数组
        for (int i = 1; i < nums.length; i++) {
            currentMax=Math.max(currentMax,nums[i]+currentMax);
            allMax=Math.max(currentMax,allMax);
        }
        return allMax;
    }
}

代码报错:

报错原因

  • currentMax 更新为 Math.max(9, -1 + 9) = 9,因为 nums[i] + currentMax 大于当前元素 -1
  • allMax 不变,仍为 9

找错

问题出在这段代码上,是用当前元素和子数组和对比

currentMax=Math.max(nums[i],nums[i]+currentMax);

第二次代码:正确

class Solution2 {
    public int maxSubArray(int[] nums) {
        if(nums.length==0 || nums==null){
            System.out.println("数组为空");
            return 0;
        }
        int currentMax=nums[0];//记录当前子数组最大和
        int allMax=nums[0];//记录整个数组最大和

        //对于当前元素,要么加入到子数组,要么从这个元素开始计和
        //如果当前元素,加上子数组,发现还没有当前元素大,那么就从当前元素开始开始算子数组
        for (int i = 1; i < nums.length; i++) {
            currentMax=Math.max(nums[i],nums[i]+currentMax);
            allMax=Math.max(currentMax,allMax);
        }
        return allMax;
    }
}

举一反三1:并输出连续子数组

这一次要多出start和end

package com.Nums;

class Solution {
    public static int maxSubArray(int[] nums) {
        if(nums.length==0 || nums==null){
            System.out.println("数组为空");
        }
        int currentMax=nums[0];//记录当前子数组最大和
        int allMax=nums[0];//记录整个数组最大和
        int start=0;//起始位置
        int end=0;//结束位置

        //对于当前元素,要么加入到子数组,要么从这个元素开始计和
        //如果当前元素,加上子数组,发现还没有当前元素大,那么就从当前元素开始开始算子数组
        for (int i = 1; i < nums.length; i++) {
            //当前元素>子数组+当前元素,从当前元素开始
            if(nums[i]>nums[i]+currentMax){
                currentMax=nums[i];
                start=i;
            }else {
                //当前元素<当前元素+子数组,把它加到子数组里,变成总和
                currentMax=nums[i]+currentMax;
            }
            //更新整个数组的总和,更新end位置
            if (currentMax>allMax){
                allMax=currentMax;
                end=i;
            }
        }
        System.out.print("最大子数组为:[");
        for (int i = start; i <= end; i++) {
            System.out.print(nums[i]+",");
        }
        System.out.print("]");
        System.out.println();
        return allMax;
    }

}

 

举一反三2:如果不用连续子数组,求最大和

这就比较简单了,我想到了先排序,然后>0的相加即可。

class Solution {
    public static int maxSubArray(int[] nums) {
        if(nums.length==0 || nums==null){
            System.out.println("数组为空");
        }
        //数组排序
        Arrays.sort(nums);

        if (nums.length==1 && nums[nums.length-1]<0){
            return nums[nums.length-1];
        }
        //数组排序
        Arrays.sort(nums);
        System.out.println(Arrays.toString(nums));

        int currentMax=nums[nums.length-1];
        int allMax=nums[nums.length-1];
        for (int i = nums.length-2; i >=0 ; i--) {
            //只要当前元素>0,总和就加上当前元素
            if(nums[i]>=0){
                currentMax=nums[i]+currentMax;
                allMax=currentMax;
            }else {
                break;
            }
        }
        return allMax;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值