写点什么

【LeetCode】连续子数组的最大和 Java 题解

作者:Albert
  • 2022-10-20
    北京
  • 本文字数:794 字

    阅读完需:约 1 分钟

题目描述

输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。


要求时间复杂度为 O(n)。


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

思路分析

  • 今天的算法题目是数组类型题目。题目需要求的是所有连续子数组的和的最大值。这里的关键字是“连续子数组”,"和"。通过关键字分析,首先想到可以用滑动窗口的思想来解决问题,由于是做加法运算,动态调整窗口的大小可以解决。

  • 除了滑动窗口的思想,我们也可以使用动态规划的方法来解决问题。动态规划是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法,题目比较灵活。具体到这个题目,我们首先定义长度为 n 的 DP 数组。使用 DP[i]表示以 nums[i]结尾的最大数组和。初始化 dp[0] = nums[0]。由于题目给出的数组中,正数,负数都有,因此,我们需要在 nums[i], 和 dp[i - 1] + nums[i] 中选取一个最大值。得出递推方程如下,dp[i] = Math.max(nums[i], dp[i - 1] + nums[i])。然后每次动态更新 ans 即可。

  • 具体实现代码如下,供参考。

通过代码

class Solution {    public int maxSubArray(int[] nums) {        int ans = Integer.MIN_VALUE;        int n = nums.length;        int[] dp = new int[n + 1];        dp[0] = nums[0];        for (int i = 1; i < n; i++) {            dp[i] = Math.max(nums[i], dp[i - 1] + nums[i]);            ans = Math.max(dp[i], ans);        }                ans = Math.max(dp[0], ans);        return ans;    }}
复制代码

总结

  • 上述算法的时间复杂度是 O(n),空间复杂度是 O(n)

  • 普通 DP 通过之后,我们再次分析代码,发现 dp[i], 只和 dp[i-1]有关,因此可以再次优化数组为变量,动态更新即可。空间复杂度可以降低为 O(1),使代码更加简洁。

  • 坚持算法每日一题,加油!我会继续更新,也欢迎算法爱好者一起交流学习。

发布于: 30 分钟前阅读数: 5
用户头像

Albert

关注

还未添加个人签名 2019-09-29 加入

LeetCode,略懂后端的RD

评论

发布
暂无评论
【LeetCode】连续子数组的最大和Java题解_算法_Albert_InfoQ写作社区