力扣算法:53. 最大子数组和

一道经典贪心、动态规划题。

题目描述:给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组 是数组中的一个连续部分。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:

输入:nums = [1]
输出:1

示例 3:

输入:nums = [5,4,-1,7,8]
输出:23


这里提供两种解法:1、贪心;2、动态规划

一、贪心

话不多说上代码:

    // 贪心
    public static int maxSubArray(int[] nums) {
        int ans = Integer.MIN_VALUE;
        int max = 0;
        for (int i = 0; i < nums.length; i++) {
            if(max > 0){
                // 不断
                max += nums[i]; // 加上当前数
                ans = Math.max(ans,max);
            }else {
                // 断
                max = nums[i]; // 当前数作为新的开头
                ans = Math.max(ans,max);
            }
        }
        return ans;
    }

我们要找的是一段连续子串,刚开始时候,将第一个元素作为首元素,添加到我们的“队列”中,此时,第一个元素就是我们的这个队列的“和”(因为我们只有一个元素),然后遍历到第二个元素,此时我们需要判断“前队列”的和是否大于0,为什么呢,如果“前队列”的和是小于0的,那么“前队列”对于我们后面要计算的队列就是累赘,我们需要“斩断”这个累赘序列,以现在所在的位置的元素为“新队列”的首元素,再向下遍历,用一个“ans”变量来接过往队列的和的最大值,就是我们最后所需要的。

二、动态规划

话不多说上代码:

    // 动态规划
    public static int maxSubArray(int[] nums){
        int[] dp = new int[nums.length];
        dp[0] = nums[0];
        for (int i = 1; i < nums.length; i++) {
            dp[i] = Math.max(dp[i - 1] + nums[i],nums[i]);
        }
        Arrays.sort(dp);
        return dp[nums.length - 1];
    }

动态规划,其实和贪心有相似之处,详细的dp(即动态规划)算法学习还需要去找其他资源,这里只提供解题方法。

我们创建dp数组,其中 dp[i] 代表的是以索引为i处的元素结尾的队列的元素和的最大值。由于0是第一位,所以dp[0]的值即为索引为0的元素的值。然后我们开始遍历,从 1 开始,我们将以前一个元素结尾的队列的最大和与当前元素相加,再和当前元素值之间取较大值,即为以当前元素结尾的队列和的最大值。最后将dp数组排序,取最大值即为我们所需要的结果。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值