LeetCode 53. Maximum Subarray

发布时间:2026/10/21 19:59:28

LeetCode 53. Maximum Subarray 题目Given an integer arraynums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.Example:Input: [-2,1,-3,4,-1,2,1,-5,4], Output: 6 Explanation: [4,-1,2,1] has the largest sum 6.Follow up:If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.几百年没做差点以为是prefix sum或者sliding window。也是看了答案才知道是dp以及并没有一次性写出来……当个复读机重复一下以前写的我觉得写挺好这道题的思路其实很简单题目要求找出数组中连续的几个数字之和的最大。由于数组是连续的因此我们以以nums[i]结尾的数组为基准来划分子问题把它表示为sum[i]那么sum[i]只有两种情况要么是nums[i]自己白手起家要么是在它前面的sum[i - 1]的基础之上锦上添花因此这个问题就变成了sum[i] max(sum[i - 1] nums[i], nums[i])。因为这题的dp状态转移比较简单只depends on前一个的状态所以其实可以不用存数组直接用变量表示。用数组class Solution { public int maxSubArray(int[] nums) { int[] dp new int[nums.length]; dp[0] nums[0]; int result dp[0]; for (int i 1; i nums.length; i) { dp[i] Math.max(nums[i], dp[i - 1] nums[i]); result Math.max(result, dp[i]); } return result; } }用变量以及根据gpt老师这是一个算法名字叫Kadanes Algorithmclass Solution { public int maxSubArray(int[] nums) { int currSum 0; // can use 0 as its calculated in the for loop int maxSum nums[0]; for (int i 0; i nums.length; i) { currSum Math.max(nums[i], currSum nums[i]); maxSum Math.max(maxSum, currSum); } return maxSum; } }番外为啥不是prefix sum或者sliding windowaccording to GPT老师为啥不用prefix sum我们需要找到最大子数组和而不是计算某个已知区间的和。如果直接枚举所有区间左端点有 \(O(n)\) 种选择。右端点有 \(O(n)\) 种选择。使用前缀和可以让每次区间求和降到 \(O(1)\)。总时间复杂度仍然是 \(O(n^2)\)。不过Prefix Sum 也可以进一步优化到 \(O(n)\)所以并不是说这题不能用前缀和而是前缀和不是最直观的解题思路。为啥不用sliding windowSliding Window 通常适用于这样的场景窗口满足某个条件时尝试扩大窗口窗口不满足条件时尝试缩小窗口缩小窗口能够让我们有规律地恢复条件。例如数组全是正数时寻找“和不超过 \(K\) 的最长连续子数组”就可以用滑动窗口。因为右端点右移会让窗口和增大左端点右移会让窗口和减小。但 Maximum Subarray 的数组可以包含任意正数和负数。滑动窗口最重要的前提是窗口条件随左右端点移动具有足够的单调性或可维护性。 这道题的最大子数组和没有提供常规滑动窗口所需的性质。以下来自久远的2019:这道题可是两年前在水算法作业的时候做过的题翻了以前的博客发现以前不会做巧了现在也不会做。题目一看就想到了动态规划可是却没想出来到底怎么划分子问题看了以前的记录才想到解法然后瞬间就写出了代码并发现之前那个代码绝壁不是我写的以前的我怎么这么水啊。这道题的思路其实很简单题目要求找出数组中连续的几个数字之和的最大。由于数组是连续的因此我们以以nums[i]结尾的数组为基准来划分子问题把它表示为sum[i]那么sum[i]只有两种情况要么是nums[i]自己白手起家要么是在它前面的sum[i - 1]的基础之上锦上添花因此这个问题就变成了sum[i] max(sum[i - 1] nums[i], nums[i])。我自己写的代码如下时间复杂度O(n)运行时间12ms只打败了5%看了下以前抄的代码发现可以用max()来简化那些if们class Solution { public: int maxSubArray(vectorint nums) { int max nums[0]; int sum nums[0]; for (int i 1; i nums.size(); i) { if (sum nums[i] nums[i]) { sum nums[i]; } else { sum nums[i]; } if (sum max) { max sum; } } return max; } };使用max()以后代码看起来清晰整洁的版本class Solution { public: int maxSubArray(vectorint nums) { int currentSum nums[0], totalSum nums[0]; for(int i1; inums.size(); i) { //Current max sum is either the current element OR current element Previous Maximum subarray) currentSum max(nums[i], currentSumnums[i]); //If the current maximum array sum is greater than the global total. Update it totalSum max(totalSum, currentSum); } return totalSum; } };2020.10.1 Java依旧差点没想到dp表达式卑微。Runtime: 1 ms, faster than 68.70% of Java online submissions for Maximum Subarray.Memory Usage: 38.9 MB, less than 96.46% of Java online submissions for Maximum Subarray.class Solution { public int maxSubArray(int[] nums) { int[] dp new int[nums.length]; dp[0] nums[0]; int max dp[0]; for (int i 1; i nums.length; i) { dp[i] Math.max(dp[i - 1] nums[i], nums[i]); if (dp[i] max) { max dp[i]; } } return max; } }还有另一种和这个思路很相似的解法设置一个currentSum和一个totalSum分别存储截至当前nums[i]的sum和全局的最大值代码如下int maxSubArray(vectorint nums) { int currentSum 0, totalSum INT_MIN; for(int i0; inums.size(); i) { //Sum till this point Current Sum till this point this element currentSum currentSum nums[i]; //If the current maximum array sum is greater than the global total. Update it totalSum max(totalSum, currentSum); //If you get current as less thn 0 then its no point in carrying forward. Make it 0 currentSum max(0,currentSum); } return totalSum; }感觉这种解法的第一句和第三句的合体就是DP解法的第一句假设当前遇到的nums[i]会使totalSum减小那么currentSum将保存当前的结果并在nums[i 1]的时候加入nums[i 1]与totalSum比较。理解的感觉不是特别到位强行解释了一番因为这个方法让我自己想我是想不到的只能在了解方法以后自己在纸上模拟一遍以上两个代码均来自于https://leetcode.com/problems/maximum-subarray/discuss/118509/C-Kadanes-Algorithm总结的很好然后看到题目底下还有个follow up说是可以用分治算法来解决看了下以前的记录发现是没有的想了一会儿还是想不到分治的解法。看了discussion里大佬的解法大概就是把原始的数组分成左右两半分别递归最后要找的max的可能性有三种要么完全是在已经分成的左右两边的一边中要么就可能是横跨左右两边并包含中间的元素。然而就算是知道了这种解法但依旧不会写代码orz 真实的递归无能了。基本上抄着大佬的代码打出了如下代码并加了点自己的注释运行时间8ms击败了35%的C submissionclass Solution { public: int maxSubArray(vectorint nums) { return maxSub(nums, 0, nums.size() - 1); } int maxSub(vectorint nums, int l, int r) { if (l r) { return INT_MIN; } // recursion for left and right part int m (l r) / 2; int lmax maxSub(nums, l, m - 1); int rmax maxSub(nums, m 1, r); // find out the max closest to the middle int ml 0, mr 0; int sum 0; for (int i m - 1; i l; i--) { sum nums[i]; ml max(ml, sum); } sum 0; for (int i m 1; i r; i) { sum nums[i]; mr max(mr, sum); } // return either the max in the left/right, or combines both side and the middle return max(max(lmax, rmax), ml mr nums[m]); } };这份代码的参考来源https://leetcode.com/problems/maximum-subarray/discuss/20452/C%2B%2B-DP-and-Divide-and-Conquer
延伸阅读

更多相关文章

2026/10/21 19:54:25

最大子数组和经典解法:从暴力枚举到Kadane算法

1. 先把问题嚼透:什么是最大子数组和如果你刷过一段时间的算法题,肯定绕不开这道“最大子数组和”。它几乎出现在每一份面试题单里,也是动态规划入门时绕不开的经典案例。题目本身很简单:给定一个整数数组,找一个具有最…

2026/10/21 19:54:25

PCA与MDS降维方法详解:线性投影与距离保持的两条路径

做用户画像聚类的时候,我拿到过一份上千维的特征表,不降维直接跑聚类,结果全是一团浆糊;后来做了降维再聚类,几个类别之间的边界立马就清楚了。从那以后我就养成了习惯:任何高维数据到手,先花十…

2026/10/21 19:54:25

架构图设计实战:从信息分层到模板化维护,告别草稿感

最近一次方案评审,评审人指着我投出来的服务调用图说:“你这张图,根本看不出重点,而且这些箭头到底是从哪发出来的?”我下意识想反驳,但低头看了一眼自己那三十二个节点、大小不一的方框、七种颜色的连线&a…

2026/10/21 23:46:47

iPhone 17 Pro录音降噪全攻略:从原理到实操

说句实话,用手机录音这件事,过去我基本不抱什么期待。直到用 iPhone 17 Pro 录了一段时间音之后,我才意识到之前的认知可以更新了——问题根本不在“手机能不能录音”,而在噪音有没有被真正压住。这篇文章就是把我这套录音降噪的完…

2026/10/21 23:46:47

4K监控与Wi-Fi 6/7 AP的PoE供电功率计算与工程选型指南

前两天刚处理完一个项目,前端的4K枪机白天跑得好好的,一到晚上红外开启就反复重启,NVR里全是掉线告警。排查到最后,问题不在摄像头,也不在网线,而是PoE供电功率差了一档。这几年安防设备升级速度确实快&…

2026/10/21 23:46:47

数据分布可视化进阶:用ggplot2绘制顶刊级小提琴图

如果你做过十几组样本的组间比较,大概会跟我有同样的纠结:箱线图太“简约”,误差条图过于朴素,把数据内部的分布形状彻底藏了起来。这时候,把密度曲线和箱线图结合起来的小提琴图,往往是性价比最高的解法。…

2026/10/21 23:46:47

从环境依赖地狱到容器化部署:Docker核心原理与避坑指南

今年年初帮一个朋友调试服务器,结果一整个晚上都耗在了环境冲突上。同一个系统里要跑三套服务,一套要 Python 3.6,一套必须 3.8,还有一套更尴尬,依赖的底层库跟前面两套直接打架。全局环境只有一个 Python,…

2026/10/21 23:46:47

知识工作插件系统:轻量级认知增强架构设计

1. 项目概述:这不是一个插件,而是一套知识工作者的“操作系统增强层”“knowledge-work-plugins”这个标题乍看像某个开源仓库的命名,但拆开来看——knowledge work(知识工作)是当代职场最核心的生产力形态&#xff0c…

2026/10/21 23:41:47

FreeToken:大模型推理中的KV缓存动态压缩技术

1. FreeToken不是“免费代币”,而是显存压缩的工程巧思看到标题里“FreeToken”这个词,很多人第一反应是加密货币圈的空投代币——毕竟带“Token”后缀的东西,十有八九和链上资产挂钩。但在这里,它和区块链、钱包、私钥毫无关系。…

2026/10/21 4:53:08

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/21 0:00:35

交通流仿真实战:IDM跟驰与MOBIL换道模型参数调优与避坑指南

简介:这份资源是面向交通工程学习者与Python开发者的微观交通流仿真项目,核心实现智能驾驶模型(IDM)下的车辆跟驰与换道行为,可用于理解速度、密度与流量之间的动态关系,适合具备Python基础、希望深入交通模…

2026/10/21 0:00:35

揭穿智能体表面顺从:用追踪代码重建任务执行确定性

1. 表面顺从不是智能体的“礼貌”,而是任务执行链路上的隐性断点最近在调试一个跨平台长周期任务调度系统时,我反复遇到一种令人困惑的现象:智能体在用户指令发出后,几乎秒级响应“已收到”“正在处理”“请稍候”,UI上…

2026/10/21 0:00:35

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事:AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里,按宣传口径,本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”,而是这话背后的含金量——它把过去只能…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑