当前位置: 首页 > news >正文

动态规划or分治法——力扣53.最大子数组和

力扣53.最大子数组和

在这里插入图片描述


【LeetCode 53】最大子数组和(Java 详细题解 + 动态规划 + 分治法拓展)

一、题目描述

给定一个整数数组 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 <= nums.length <= 10⁵
  • -10⁴ <= nums[i] <= 10⁴

进阶:
如果你已经实现 O(n) 的解法,请尝试使用分治法实现。


二、思路分析

这道题的核心思想是:

对于数组中的每一个元素,判断“以它结尾的最大子数组和”是多少。

换句话说,我们在遍历数组时,需要不断地记录“当前最大连续和”,并实时更新“全局最大值”。

1. 动态规划思路(Kadane 算法)

dp[i] 表示 以第 i 个元素结尾的最大连续子数组和,则有:

dp[i] = max(nums[i], dp[i-1] + nums[i])

解释:

  • 如果 dp[i-1] + nums[i]nums[i] 大,说明把当前元素接到前面的子数组更优;
  • 否则,从当前元素重新开始计算。

最终答案就是所有 dp[i] 中的最大值。


三、代码实现(Java)

class Solution {public int maxSubArray(int[] nums) {// 边界条件if (nums == null || nums.length == 0) {return 0;}int currentSum = nums[0];  // 当前子数组的最大和int maxSum = nums[0];      // 全局最大和// 从第二个元素开始遍历for (int i = 1; i < nums.length; i++) {// 如果前面的和为负数,不如从当前元素重新开始currentSum = Math.max(nums[i], currentSum + nums[i]);maxSum = Math.max(maxSum, currentSum);}return maxSum;}
}

在这里插入图片描述


四、复杂度分析

项目分析
时间复杂度O(n),只需一次遍历数组
空间复杂度O(1),只使用常数级变量保存当前和与最大和

五、举例讲解

nums = [-2,1,-3,4,-1,2,1,-5,4] 为例:

inums[i]currentSum 计算currentSummaxSum
0-2初始化-2-2
11max(1, -2+1)=111
2-3max(-3, 1-3)=-2-21
34max(4, -2+4)=444
4-1max(-1, 4-1)=334
52max(2, 3+2)=555
61max(1, 5+1)=666
7-5max(-5, 6-5)=116
84max(4, 1+4)=556

最终结果:maxSum = 6


六、进阶:分治法(Divide and Conquer)

除了线性动态规划,还可以使用分治法解决。

思想

将数组分为左右两部分:

  • 最大子数组要么在左半部分;
  • 要么在右半部分;
  • 要么跨越中点。

我们递归计算左右部分的最大子数组和,再计算中间跨越部分的最大和。

实现思路简要

class Solution {public int maxSubArray(int[] nums) {return divide(nums, 0, nums.length - 1);}private int divide(int[] nums, int left, int right) {if (left == right) return nums[left];int mid = (left + right) / 2;int leftSum = divide(nums, left, mid);int rightSum = divide(nums, mid + 1, right);int crossSum = cross(nums, left, right, mid);return Math.max(Math.max(leftSum, rightSum), crossSum);}private int cross(int[] nums, int left, int right, int mid) {int leftMax = Integer.MIN_VALUE;int sum = 0;for (int i = mid; i >= left; i--) {sum += nums[i];leftMax = Math.max(leftMax, sum);}int rightMax = Integer.MIN_VALUE;sum = 0;for (int i = mid + 1; i <= right; i++) {sum += nums[i];rightMax = Math.max(rightMax, sum);}return leftMax + rightMax;}
}

在这里插入图片描述

复杂度分析:

  • 时间复杂度:O(n log n)
  • 空间复杂度:O(log n)(递归栈)

七、总结对比

方法思路时间复杂度空间复杂度特点
动态规划(Kadane)从左到右线性扫描O(n)O(1)简洁高效
分治法递归拆分区间O(n log n)O(log n)理论性强、适合理解问题结构

八、总结

本题是经典的动态规划入门题,掌握后能帮助你理解一类“区间连续最优问题”。
无论是求最大子数组和,还是其他类似的最大连续区间问题,Kadane 算法都是最重要的基础算法之一。


http://www.dtcms.com/a/523900.html

相关文章:

  • 【解决】蚁剑下载插件过慢、下载插件无法安装等问题
  • 在dify平台智能体工作流中迭代和循环如何选择?
  • UE5 蓝图-13:HUD蓝图的 beginPlay里创建了 mainUI 蓝图对象,蓝图函数库里的函数 getMainUI 以及 getPawn
  • 11.盛最多水的容器
  • 【C++】stack和queue:优先级队列的使用及底层原理
  • 兰州营销型网站建设优化游戏的软件
  • 廊坊做网站的公司专门做孕婴用品的网站
  • 3. char、字符串、字符串数组、二维字符数组、char[] 的区别与联系
  • 数据结构C语言
  • RTX5060Ti安装cuda加速的openCV
  • 金融网站建设重庆网站建设电脑版
  • 超越图像:机器学习之生成对抗网络(GAN)在时序数据增强与异常检测中的深度实践
  • C# 企业微信机器人消息推送
  • 原生日历表
  • 做网站购买服务器多少钱三亚房地产网站制作
  • 新网站的建设工作织梦软件怎么使用域名做网站
  • 暖手宝方案开发,暖手宝MCU控制方案开发设计
  • SpringCloud启动——MybatisPlus(MP)
  • 图解Java链表反转:迭代法详解
  • SOGS压缩技术
  • SQLiteStudio下载安装图解教程(附安装包)
  • 【图像超分】论文复现:轻量化超分 | RLFN的Pytorch源码复现,跑通源码,整合到EDSR-PyTorch中进行训练、测试
  • 吉利汽车携手阿里云函数计算,打造新一代 AI 座舱推理引擎
  • 基于mormot.net.async.pas实现一个纯粹的Socket Server
  • FastReport .NET 2026.1 全新发布: 统一Demo中心、全新Ribbon界面、Excel公式导出、Word图像质量设置等重磅升级!
  • 网站后台上传图片脚本错误个人博客大全
  • 郑州水晶奖杯制作wordpress加载优化
  • 【计算机网络笔记】第二章 应用层 (Application Layer)
  • 东营聊城网站建设seo门户网站建设
  • DigitalOcean Gradient™ 平台上线 fal 四款多模态 AI 模型:快速生成图像与音频