搞定leetcode面试经典150题之 Kadane 算法

系列博客目录



53. 最大子数组和

链接
思路:自己在思考的时候总是站在第i个数的位置思考是否应该加上下一个(第i+1的)数字,但是这样我们没法方便的便利数组,应该反过来想,我们是否应该把上一个位置以及之前结果的和加入到现在的位置的数字作为一个新的结果。这样就形成了动态规划的思想。

只有以下几种情况

  1. 如果之前的数组和是正数,当前数也是正数,那么和必然大于当前数字
  2. 如果之前的数组和是正数,当前数是负数,那么和必然大于当前数字,
  3. 如果之前的数组和是负数,当前数是正数,相加必然小于当前数字
  4. 如果之前的数组和是负数,当前数也是负数,相加必然小于当前数字

我们可以得出一条结论:如果之前的数组和为负数那么只选取当前数字作为结果会更大,如果之前的数组和为正数,那选取当前数字和之前结果的和会更大。

class Solution {
    public int maxSubArray(int[] nums) {
        int sum = 0;
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < nums.length; i++) {
            sum = sum>0 ? sum+nums[i]:nums[i];
            max = Math.max(max,sum);
        }
        return  max;
    }
}

918.环形子数组的最大和

链接
思路:首先遍历一遍,得到最大值res不用利用到数组是环形这个特点的情况。然后再计算如果是环形,那么与之前的res进行比较,哪个大保留哪个。如何处理环形呢,数组中某一个下标,我们要知道从这个下标一直到数组最后位置,再从最前位置到现在位置前一个位置的最大值。我们这时候不考虑,比如 这个位置的最大值就是他和他后面一个,这样的不用利用到环形的情况,因为这在第一次遍历中我们以及记录下来了。为了一定要利用到环形的特点,也就是说针对第i个位置,我们要把i到nums.length - 1 的所有值加起来,在与开头的0到i-1位置的最大值相加,得到这个位置的利用了环形这个特点的最大值。0到i-1位置的最大值还是正常计算,不用说一定要把i到i-1的值都加起来。

class Solution {
    public int maxSubarraySumCircular(int[] nums) {
        int n = nums.length;
        int[] leftMax = new int[n];
        // 对坐标为 0 处的元素单独处理,避免考虑子数组为空的情况
        leftMax[0] = nums[0];
        int leftSum = nums[0];
        int pre = nums[0];
        int res = nums[0];
        for (int i = 1; i < n; i++) {
            pre = Math.max(pre + nums[i], nums[i]);
            res = Math.max(res, pre);
            leftSum += nums[i];
            leftMax[i] = Math.max(leftMax[i - 1], leftSum);
        }

        // 从右到左枚举后缀,固定后缀,选择最大前缀
        int rightSum = 0;
        for (int i = n - 1; i > 0; i--) {
            rightSum += nums[i];
            res = Math.max(res, rightSum + leftMax[i - 1]);
        }
        return res;
    }
}

作者:力扣官方题解
链接:https://leetcode.cn/problems/maximum-sum-circular-subarray/solutions/2350660/huan-xing-zi-shu-zu-de-zui-da-he-by-leet-elou/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值