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

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

给你一个整数数组 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 和 1在一起累加,计算起点一定从1开始,因为负数只会拉低总和,这就是贪心贪的地方!

  • 局部最优:当前 “连续和” 为负数的时候立刻放弃,从下一个元素重新计算 “连续和”,因为负数加上下一个元素 “连续和” 只会越来越小。
  • 全局最优:选取最大“连续和”

局部最优的情况下,并记录最大的 “连续和” ,可以推出全局最优

不断调整最大子序和区间的起始位置,区间终止位置是不用调整的,因为区间的终止位置,在count取得最大值了,及时记录下来了。这相当于是用result记录最大子序和区间和(变相的算是调整了终止位置) 

if (count > result) result = count;

C++代码:

class Solution {
public:int maxSubArray(vector<int>& nums) {int result = INT32_MIN;int count = 0;for (int i = 0; i < nums.size(); i++) {count += nums[i];if (count > result) { // 取区间累计的最大值(相当于不断确定最大子序终止位置)result = count;}if (count <= 0) count = 0; // 相当于重置最大子序起始位置,因为遇到负数一定是拉低总和}return result;}
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

 二、动态规划 

dp[i] : 表示包括 i 之前的最大连续子序列和

i = 0,dp[0] = -2

i = 1,count = (-2) + 1 = -1,在count 和 nums[1] = 1中选取最大值,即 dp[1] = max(dp[0] + nums[1],nums[1]); 所以dp[1] = 1

i = 2,由于前面已经计算过包括i = 1之前的最大连续子序列和,并且将值保存在 dp[1] 里,所以count = dp[1] + (-3) = 1 + (-3) = -2,接着在count 和 nums[2] = -3中选取最大值,即 dp[2] = max(dp[1] + nums[2],nums[2]);所以dp[2] = -2表示包括i = 2之前的最大连续子序列和。同理,如下推导

i = 3,count = dp[2] + 4 = 2,dp[3] = max(2,4);所以dp[3] = 4。发现 count < nums[3],这时候取最大值就可以让dp[3] = nums[3],表示接下来,可以调整起点,让 i = 3 为起点

i = 4,count = dp[3] + (-1) = 3,dp[4] = max(3,-1);所以dp[4] = 3.发现count > nums[4]的,表示可以保持让 i = 3为起点

i = 5,count = dp[4] + 2 = 5,dp[5] = max(5,2);所以dp[5] = 5.发现count > nums[5]的,表示可以保持让 i = 3为起点

i = 6,count = dp[5] + 1 = 6,dp[6] = max(6,1);所以dp[6] = 6.发现count > nums[6]的,表示可以保持让 i = 3为起点

i = 7,count = dp[6] + (-5) = 1,dp[7] = max(1,-5);所以dp[7]=1.发现count > nums[7]的,表示可以保持让 i = 3为起点

i = 8,count = dp[7] + 4 = 5,dp[8] = max(5,4);所以dp[8] = 5.发现count > nums[8]的,表示可以保持让 i = 3为起点

① count = dp[i-1] + nums[i];② dp[i] = max(count,nums[i]);↓↓↓↓
③ dp[i] = max(dp[i-1] + nums[i],dp[i]);
class Solution {
public:int maxSubArray(vector<int>& nums) {if (nums.size() == 0) return 0;vector<int> dp(nums.size(), 0); // dp[i]表示包括i之前的最大连续子序列和dp[0] = nums[0];int result = dp[0];for (int i = 1; i < nums.size(); i++) {dp[i] = max(dp[i - 1] + nums[i], nums[i]); // 状态转移公式if (dp[i] > result) result = dp[i]; // result 保存dp[i]的最大值}return result;}
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

>>优化空间复杂度

class Solution {
public:// 动态规划 + 优化空间复杂度int maxSubArray(vector<int>& nums) {if(nums.size() == 0) return 0;int pre = nums[0];int result = nums[0];for(int i=1; i<nums.size(); i++) {pre = max(pre + nums[i],nums[i]); if(pre > result) result = pre;}return result;}
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

参考和推荐文章、视频

代码随想录 (programmercarl.com)

贪心算法的巧妙需要慢慢体会!LeetCode:53. 最大子序和_哔哩哔哩_bilibili

来自代码随想录的课堂截图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/126736.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Camera FW 里的requestId和frameId

安卓相机frameworks里面经常出现requestId和frameId&#xff0c;最近简单看了一下代码&#xff0c;发现相关流程还是很复杂的&#xff0c;总结来看requestId 就是上层&#xff08;java&#xff09;发送的repeating(capture)请求的id&#xff0c;是从0开始递增的。 这是CameraD…

Godot 官方2D游戏笔记(1):导入动画资源和添加节点

前言 Godot 官方给了我们2D游戏和3D游戏的案例&#xff0c;不过如果是独立开发者只用考虑2D游戏就可以了&#xff0c;因为2D游戏纯粹&#xff0c;我们只需要关注游戏的玩法即可。2D游戏的美术素材简单&#xff0c;交互逻辑简单&#xff0c;我们可以把更多的时间放在游戏的玩法…

Transformer学习

这里写目录标题 Seq2Seq语音翻译为何不直接用语音辨识机器翻译&#xff1f;语法分析文章归类问题目标检测 TransformerEncoder结构multi-head attention block为何batch-norm 不如 layer-norm&#xff1f; Decoder结构decoder流程decoder结构decoder比encoder多了一个masked se…

数据结构--排序(2)

前言 排序&#xff08;1&#xff09;链接入口 快速排序 链接入口 归并排序 思想&#xff1a;将数组利用递归形式一直对半平分&#xff0c;将一组完整的数组分成若干份&#xff0c; 接着将它们相邻两个分为一组&#xff0c;进行排序&#xff0c;排序之后组合成一组&#xff0…

格雷希尔针对汽车空调高压管异型管口快速密封的G72R高压连接器

汽车散热是汽车热管理的重要部件&#xff0c;不管是燃油车还是新能源车&#xff0c;散热都是必不可少的零部件&#xff0c;从散热水箱、到车用空调冷凝器、蒸发器、空调高压管件等&#xff0c;由于位置和固定方式等影响&#xff0c;虽然管件直径比较标准&#xff0c;但接口部分…

基于Springboot实现旧物置换网站平台演示【项目源码+论文说明】分享

基于Springboot实现旧物置换网站平台演示 摘要 随着时代在一步一步在进步&#xff0c;旧物也成人们的烦恼&#xff0c;许多平台网站都在推广自已的产品像天猫、咸鱼、京东。所以开发出一套关于旧物置换网站成为必需。旧物置换网站主要是借助计算机&#xff0c;通过对用户进行管…

电压放大器在心电图中的作用是什么

心电图是一种常用的临床检测方法&#xff0c;用于评估心脏的电活动。在进行心电图检测时&#xff0c;为了保证测量结果的准确性和可靠性&#xff0c;需要使用一种特殊的电压放大器&#xff0c;即心电放大器&#xff0c;来增强心电信号并抑制噪音和干扰。 心电图信号具有微弱的幅…

python scanpy spatial空转全流程

Spatial mapping of cell types across the mouse brain (1/3) - estimating reference expression signatures of cell types — cell2location documentation Spatial mapping of cell types across the mouse brain (2/3) - cell2location — cell2location documentation #…

elementui修改message消息提示颜色

/* el弹出框样式 */ .el-message {top: 80px !important;border: 0; }.el-message * {color: var(--white) !important;font-weight: 600; }.el-message--success {background: var(--themeBackground); }.el-message--warning {background: var(--gradientBG); }.el-message--…

R实现数据分布特征的视觉化——多笔数据之间的比较

大家好&#xff0c;我是带我去滑雪&#xff01; 如果要对两笔数据或者多笔数据的分布情况进行比较&#xff0c;Q-Q图、柱状图、星形图都是非常好的选择&#xff0c;下面开始实战。 &#xff08;1&#xff09;绘制Q-Q图 首先导入数据bankwage.csv文件&#xff0c;该数据集…

SAP从入门到放弃系列之QM样本确定

目录 一、样本确定概述-Sample Determination1.1、样本确定的规则1.2、规则维护方式1.2.1、物料主数据的维度1.2.2、任务清单的维度1.2.2.1、采样过程-Sampling Procedure 二、采样过程维护2.1 采样过程-Sampling Procedures概述样本类型评估模式检验点 一、样本确定概述-Sampl…

基于SSM的旅游网站设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…