LeetCode-53-最大子数组和

【中等】力扣算法题解析LeetCode53:最大子数组和 要求找出数组中连续子数组的最大和。使用Kadane算法,通过动态规划思想,遍历数组时维护以当前元素结尾的最大子数组和(currentMax)和全局最大值(globalMax)。时间复杂度O(n),空间复杂度O(1)。具体实现为:初始化currentMax和globalMax为第一个元素,遍历数组时更新currentMax为当前元素或当前元素加前一个currentMax的较大值,并用currentMax更新globalMax。最终返回globalMax。 阅读详情

题目

给你一个整数数组 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, 3, 10,-4, 7, 2, -5}
从头到尾累加数组,第一步加上第一个数字 1 和为 1 ,第二步加上数字 -2,和为 -1 ,注意:由于之前累计的和为 -1,小于0,那么之后和3加为 2 小于 3本身。也就是说从第一个开始的字数组累加的和会小于从 3 开始的累加的和。因此之前的和就可以舍弃。
从三个数字重新开始累加,得到的和为 3, 第四步加 10,得到13,第五步加上 -4和为 9,有与 -4 是负数,因此累加之后的和比之前小,所以需要一个变量把之前的和保存起来,因为有可能这个和就是最后的最大值。
代码示例:

public int FindGreatestSumOfSubArray(int[] array) {
	//临界条件判断
	if(array == null || array.length <= 0) {
		return 0;
	}
	//记录当前累加的和
	int record = 0;
	//用来保存最大值,赋值为0x80000000,可能数组都为负数
	int max = Integer.MIN_VALUE;
	for(int i = 0; i < array.length; i++) {
		if(record <= 0) {
			record = array[i];
		} else {
			record += array[i];
		}
		if(record > max) {
			max = record;
		}
	}
	return max;
}
总结

这里需要注意的是

  1. 这里判断无效输入返回值也是0;
  2. 若是需要判断是无效输入还是子数组的最大和就是0,可以增加一个boolean类型的变量来标记是否是无效输入。
思路二

    使用动态规划实现:
F(i):以array[i]为末尾元素的子数组的和的最大值,子数组的元素的相对位置不变
F(i)=max(F(i-1)+ array[i] , array[i])
record:所有子数组的和的最大值
record=max(record,F(i))

如数组[6, -3, -2, 7, -15, 1, 2, 2]
初始状态:
F(0)= 6
record = 6
i=1:
F(1)=max(F(0) - 3,-3)= max(6 - 3,3)= 3
record= max(F(1),record)= max(3,6)= 6
i=2:
F(2)= max(F(1)- 2,-2)= max(3 - 2,-2)= 1
record= max(F(2),record)= max(1,6)= 6
i=3:
F(3)= max(F(2)+ 7,7)= max(1+7,7)= 8
record= max(F(2),record)= max(8,6)= 8
i=4:
F(4)= max(F(3)-15,-15)= max(8-15,-15)= -7
record=max(F(4),record)= max(-7,8)= 8
以此类推
最终record的值为8

代码示例:

public int FindGreatestSumOfSubArray(int[] array) {
	//临界条件判断
	if(array == null || array.length <= 0) {
		return 0;
	}
	//记录当前所有子数组和的最大值
	int record = array[0];
	//包含array[i]的连续数组最大值
	int max = array[0];
	for(int i = 1; i < array.length; i++) {
		max = Math.max(max + array[i], array[i]);
		record = Math.max(max, record);
	}
	
	return record;
}
动态规划的求解过程

经典动态规划问题(理解「无后效性」)

1.定义状态(子问题)

设计状态思路: 动态规划的思想是通过解决一个一个简单的问题,进而把简单的问题的解组成复杂的问题的解。

例如,示例 1 输入数组是 [-2,1,-3,4,-1,2,1,-5,4] ,我们可以求出以下子问题:

  • 子问题 1:以 −2 结尾的连续子数组的最大和是多少;
  • 子问题 2:以 1 结尾的连续子数组的最大和是多少;
  • 子问题 3:以−3 结尾的连续子数组的最大和是多少;
  • 子问题 4:以 4 结尾的连续子数组的最大和是多少;
  • 子问题 5:以 −1 结尾的连续子数组的最大和是多少;
  • 子问题 6:以 2 结尾的连续子数组的最大和是多少;
  • 子问题 7:以 1 结尾的连续子数组的最大和是多少;
  • 子问题 8:以 −5 结尾的连续子数组的最大和是多少;
  • 子问题 9:以 4 结尾的连续子数组的最大和是多少;

子问题 1: 以 −2 结尾的连续子数组的最大和是多少?
以 −2 结尾的连续子数组是 [-2],因此最大和就是 −2。
子问题 2: 以 1 结尾的连续子数组的最大和是多少?
以 1 结尾的连续子数组有 [-2,1] 和 [1] ,其中 [-2,1] 就是在「子问题 1」的后面加上 1 得到。
−2+1=−1<1 ,因此「子问题 2」 的答案是 1。
可以得出: 如果编号为 i 的子问题的结果是负数或者 0 ,那么编号为 i + 1 的子问题就可以把编号为 i 的子问题的结果舍弃掉,这是因为:

  • 一个数 a 加上负数的结果比 a 更小;
  • 一个数 a 加上 0 的结果不会比 a 更大;
  • 而子问题的定义必须以一个数结尾,因此如果子问题 i 的结果是负数或者 0,那么子问题 i + 1 的答案就是以 nums[i] 结尾的那个数。
定义状态(定义子问题)

dp[i]:表示以 nums[i] 结尾 的 连续 子数组的最大和。

说明:「结尾」和「连续」是关键字。

状态转移方程

由于 nums[i] 一定会被选取,并且以 nums[i] 结尾的连续子数组与以 nums[i - 1] 结尾的连续子数组只相差一个元素 nums[i] 。
假设数组 nums 的值全都严格大于 0,那么一定有 dp[i] = dp[i - 1] + nums[i]。
可是 dp[i - 1] 有可能是负数,于是分类讨论:

  • 如果 dp[i - 1] > 0,那么可以把 nums[i] 直接接在 dp[i - 1] 表示的那个数组的后面,得到和更大的连续子数组;
  • 如果 dp[i - 1] <= 0,那么 nums[i] 加上前面的数 dp[i - 1] 以后值不会变大。于是 dp[i] 从数组当前数开始,此时单独的一个 nums[i] 的值,就是 dp[i]。
  • 以上两种情况的最大值就是 dp[i] 的值,写出如下状态转移方程:

dp [ i ] = { dp [ i − 1 ] + n u m s [ i ] , d p [ i − 1 ] > 0 nums [ i ] , d p [ i − 1 ] ≤ 0 \textit{dp}[i] = \begin{cases} \textit{dp}[i-1]+nums[i], & dp[i−1]>0 \\ \textit{nums}[i], & dp[i−1]≤0 \end{cases} dp[i]={dp[i−1]+nums[i],nums[i],​dp[i−1]>0dp[i−1]≤0​

​状态转移方程还可以这样写,反正求的是最大值,也不用分类讨论了,就这两种情况,取最大即可,因此还可以写出状态转移方程如下:
dp [ i ] = m a x { n u m s [ i ] , d p [ i − 1 ] + n u m s [ i ] } \textit{dp}[i] = max\{nums[i],dp[i−1]+nums[i]\} dp[i]=max{nums[i],dp[i−1]+nums[i]}

思考初始值

dp[0] 根据定义,只有 1 个数,一定以 nums[0] 结尾,因此 dp[0] = nums[0]。

思考输出

这里每一小步的状态定义不是题目中的问题的定义,不能直接将最后一个状态返回回去;
应该在所有的状态里面找最大值,并返回

public static int maxSubArray(int[] nums) {
    if (nums == null || nums.length < 1) {
        return 0;
    }

    int[] dp = new int[nums.length];
    dp[0] = nums[0];
    int max = dp[0];

    for (int i = 1; i < nums.length; ++i) {
        if (dp[i - 1] < 0) {
            dp[i] = nums[i];
        } else {
            dp[i] = dp[i - 1] + nums[i];
        }

        max = Math.max(max, dp[i]);
    }

    return max;
}

相关推荐

REALTEK PKE8710ECF开发板入手试玩(一)

REALTEK PKE8710ECF开发板入手试玩

lbqhope的专栏 690

LeetCode53.最大子数组和

偶然看到的一篇题解,作者思路清晰,循序渐进,写的很不错,学习下写作思路

cosuyo的博客 495

平面变压器PCB绕组设计实战:从原理到布局的工程考量

本文深入探讨了平面变压器PCB绕组设计的工程实践,从基础原理到布局优化,涵盖了电流密度、层间绝缘、绕组拓扑结构等关键参数。通过实战案例分享,解析了高频应用中的集肤效应、邻近效应等挑战,并提供了热管理和EMC优化的实用技巧,助力工程师在服务器电源、车载充电器等空间敏感场景实现高效设计。

weixin_42666036的博客 452

leetCode 53.最大子数和 图解 + 贪心算法/动态规划+优化

由于前面已经计算过包括i = 1之前的最大连续子序列和,并且将值保存在 dp[1] 里,所以count = dp[1] + (-3) = 1 + (-3) = -2,接着在count 和 nums[2] = -3中选取最大值,即。发现 count < nums[3],这时候取最大值就可以让dp[3] = nums[3],表示接下来,可以调整起点,让 i = 3 为起点。count = (-2) + 1 = -1,在count 和 nums[1] = 1中选取最大值,即。贪心算法的巧妙需要慢慢体会!

呵呵哒!的博客 1937

Windows安装Pytorch3d

pytorch和pytorch3d版本对应关系如下:https://github.com/facebookresearch/pytorch3d/releasescuda和NVIDIA CUB版本对应关系如下:https://github.com/NVIDIA/cub/releases?page=1本人配置如下:GPU:1050TiCUDA:11.1python:3.8。

Snakewood的博客 4285

保姆级教程:用Protege 5.5.0从零构建你的第一个知识图谱(附实战案例文件)

本文提供了一份详细的Protege 5.5.0使用指南,从零开始构建知识图谱。涵盖环境配置、本体结构设计、实例填充到可视化展示的全流程,特别适合初学者快速掌握知识建模技术。通过实战案例演示,帮助读者理解如何定义类、属性及建立实例关系,是学习知识图谱构建的实用教程。

weixin_42548816的博客 553

leetcode算法53.最大子数组和

???????????? 哈喽!大家好,我是【学无止境小奇】,一位热爱分享各种技术的博主!???????????? ⭐【学无止境小奇】的创作宗旨:每一条命令都亲自执行过,每一行代码都实际运行过,每一种方法都真实实践过,每一篇文章都良心制作过。✊✊✊ ⭐【学无止境小奇】的博客中所有涉及命令、代码的地方,除了提供图片供大家参考,另外会在图片下方提供一份纯文本格式的命令或者代码方便大家粘贴复制直接执行命令或者运行代码。???????????? ⭐如果你对技术有着浓厚的兴趣,欢迎关注【学无止境小奇】,欢迎大

真正的大师永远怀着一颗学徒的心 1255

ArcGIS供地图斑图形及属性入库操作(附练习数据)

已知数据: 供地图斑位置图。 供地图斑表格 成果要求:将供地图斑导入mdb数据库并将供地图斑表格的属性进行挂接。 接下来我们开始操作: 1、 打开arcmap,在目录内连接的文件夹内找到供地图斑位置图。图片 2、 将annotation和polygon添加到arcmap图片 3、 右击文件所在文件夹新建mdb数据库图片 4、 右击数据库新建要素数据集。(要素数据集非常重要,稍后所有操作都在数据集内进行)选择图斑投影方式及代号。图片 5、 右击要素数据集—导入(将图层内的数据导入数据库)图片 6、 数据导入.

qq_43173805的博客 8130

LeetCode 53.最大子数组和——详解

内含题目误区分析,思路详解 走过路过千万别错过 不看痛失一个亿

m0_62955663的博客 462

pb插入ole控件点击insert+control时自动关闭解决办法

也就是说pb搜索CLSID的子项保存在OLE Object Bitmaps中,当搜索CLSID中的DLL或OCX控件和PB有冲突时,CLSID后面的DLL、OCX控件就不会保存在OLE Object Bitmaps中,也就是说OLE Object Bitmaps没有完全加载所有控件,有的控件冲突导致中断使PB报错,找出冲突的控件是关键。进行对出问题的控件反注册,如果提示反注册成功,打开PB的OLE控件看是否报错,如果还报错返回步骤(三)循环查找。,再进入注册表看到的是最正确的。来注册会莫名的冲突,但是用。

悠闲饭团的博客 710

YOLO26 电子产品零部件质检:缺陷检测 + Streamlit

YOLO26s 电子质检链路:1100 张工业零部件图 (4 类缺陷) → 增强 (blur+shear+低光照) → 150 epoch → mAP@0.5=0.91 → Streamlit 质检界面 (上传/摄像头双模式) → 缺陷严重度分级 (pass/minor/major/critical)。核心贡献:blur+shear 模拟产线振动和视角偏移, 使模糊场景 recall 从 72% 提升至 78%;Streamlit 一键部署, 无需前端经验。建议先收集 200 张纯正常件做负样本防过检;

m0_71589036的博客 374

leetcode53. 最大子数组和

1.题目描述: 给你一个整数数组nums,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组是数组中的一个连续部分。 2.暴力解法:得到所有子数组的和,取其中最大值,超时。 class Solution { public int maxSubArray(int[] nums) { int max = Integer.MIN_VALUE; for (int i = 0; i < nums.length; i++) {

kkkkuuga的博客 728

PyQt5简介和安装

在initUI方法中,设置了窗口的标题和大小,并创建了一个按钮。PyQt5是一个功能强大的Python界面开发框架,可以轻松创建跨平台的图形用户界面应用程序。本文介绍了PyQt5的简介和安装方法,并提供了一个简单的示例应用程序来演示PyQt5的基本用法。PyQt5是一个功能强大的Python界面开发框架,它提供了丰富的工具和组件,用于创建跨平台的图形用户界面(GUI)应用程序。信号是控件发出的事件,槽是与之关联的处理函数。接下来,我们将编写一个简单的PyQt5应用程序,以演示PyQt5的基本用法。

XdKwargs的博客 222

【LeetCode力扣】189 53 轮转数组 | 最大子数组和

189. 轮转数组 - 力扣(LeetCode)53. 最大子数组和 - 力扣(LeetCode)我们可以使用额外的数组来将每个元素放至正确的位置。用 len 表示数组的长度,我们遍历原数组,将原数组下标为 i 的元素放至新数组下标为 (i+k) % len 的位置,最后将新数组拷贝至原数组即可。

Hacynn的博客 1920

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

leetcode_53 最大子数组和

本文探讨了求解最大子数组和的四种方法:暴力枚举(O(n²))、动态规划(O(n))、贪心算法和分治策略。动态规划通过状态转移方程优化空间至O(1);贪心算法采用"抛弃负收益"策略;分治法则将问题分解为左右子区间处理,需维护区间和、左右端点极值等参数,时间复杂度为O(nlogn)。其中动态规划和贪心解法最为高效,空间复杂度均为O(1),体现了不同算法思想在解决同一问题时的多样性与优化思路。

bdn_nbd的博客 1109

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

LeetCode 一题多解 | 53. 最大子数组和:五种解法完全手册

点击上方“五分钟学算法”,选择“星标”公众号重磅干货,第一时间送达 作者:nettee 公众号:面向大象编程一、原题描述 LeetCode 53. Maximum S...

程序员吴师兄的博客 7103

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

[Golang]力扣Leetcode - 53.最大子数组和(动态规划)

[Golang]力扣Leetcode - 53.最大子数组和(动态规划)

皮埃尔的博客 386

力扣53.最大子数组和

力扣,C++,菜菜奋斗小记

2402_88149600的博客 416

力扣(LeetCode)100题:53.最大子数组和

本文介绍了使用动态规划解决最大子数组和问题的方法。核心思路是定义dp[i]为以nums[i]结尾的子数组最大和,通过比较前序和的正负来决定是否连接前序子数组。具体实现时,初始化dp[0]=nums[0],然后遍历数组,若前序和为正则连接,否则从当前元素重新开始。最终返回dp数组中的最大值。该方法的时间复杂度为O(n),空间复杂度为O(n)。示例展示了如何通过该算法找到最优子数组[4,-1,2,1],其和为6。这种设计保证了子问题无后效性,能高效求解最大连续子数组和问题。

sweet_ran的博客 337

力扣53. 最大子数组和

/如果前面的pre大于0则对最大子数组和有贡献,pre=pre+num[i],否则为nums[i]。输入:nums = [-2,1,-3,4,-1,2,1,-5,4] 输出:6 解释:连续子数组 [4,-1,2,1] 的和最大,为 6。给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。输入:nums = [5,4,-1,7,8] 输出:23。

weixin_46161238的博客 97

力扣-53.最大子数组和

力扣-53.最大子数组和。解题思路分析

weixin_67851619的博客 885

LeetCode53:最大子数组和

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

2301_80351584的博客 536

力扣(LeetCode) 53.最大子数组和 动态规划解决

力扣(LeetCode) 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 <

qq_58642780的博客 319

LeetCode——53. 最大子数组和(Java)

Kadane 算法是一种非常高效的解决方案,适用于求解最大子数组和问题。它通过动态规划的思想,逐步计算每个位置的最大子数组和,并在过程中更新全局的最大值。这种方法不仅时间复杂度低,而且空间复杂度也非常低,非常适合处理大规模数据。

weixin_46024617的博客 1541

dp 力扣 53. 最大子数组和

力扣 53. 最大子数组和 思路: 使用动态规划思想 首先先看题目要求,寻找最大和的连续子数组 dp[i]定义为从0到i的连续子数组和的值的集合 dp状态为max 根据题目可得 如果前i个连续子数组和小于0 则不与后面的子数组接上。 dp状态转移为dp[i]=nums[i]+max(dp[i-1],0) 代码: class Solution { public: int maxSubArray(vector<int>& nums) { int dp[100005]

爪蛙毁一生的博客 280

53. 最大子数组和 - 力扣(LeetCode)

这样每一步都可以计算当前前缀和与最小前缀和的差值,这个差值就是当前可能的最大子数组和。最大子数组和可以通过找到某个位置的前缀和减去之前的最小前缀和来得到。,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。输入数组是 [−2, 1, −3, 4, −1, 2, 1, −5, 4]输入:nums = [-2,1,-3,4,-1,2,1,-5,4]res = 6,对应的最大子数组是 [4, -1, 2, 1]。解释:连续子数组 [4,-1,2,1] 的和最大,为 6。

q1111111da的博客 1168
上一篇: 剑指offer-37-两个链表的第一个公共结点
下一篇: 剑指offer-38-数字在排序数组中出现的次数
CodAlun
博客等级 码龄8年 46粉丝 96原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值