刷题记录 贪心算法-4:53. 最大子数组和

server/2025/2/4 2:37:08/

题目:53. 最大子数组和

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例 1:

输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

示例 2:

输入:n = 1
输出:["()"]

提示:

  • 1 <= n <= 8

一、模式识别

1.算法>贪心算法

局部最优解:连续和为负时放弃连续和,重新开始连续和

局部到全局:选取多个子数组的最大连续和

反例:(象征性的写一下,能用贪心的都不会有,而且也不用证明)

代码随想录里也说这道题的贪心并不好想

不仅不好想,而且仔细想会发现连续和为负时放弃连续和只是一个必要条件,

2.动态规划

序列问题:经典动态规划问题,所以其实本题更容易想到动态规划解法

(1)定义:dp[i]: 以nums[i]为结尾的最大数字和

(2)递推公式:dp[i] = max(dp[i - 1] +num, num)

dp[i - 1]是以前一个数字为结尾的最大值

由于连续数组条件限制,因此在本轮中只能在加入以前的连续序列重新开始之间做出选择

(3)初始化:由递推,任意dp[i]依赖于dp[i - 1],需要从dp[0]开始

(4)遍历顺序:由递推,dp[i]依赖于dp[i - 1],需要从前往后

二、代码实现

1.暴力解法

连续子序列这么明确的条件,用两层嵌套循环分别表示起始点和终止点最容易实现了

python">class Solution:def maxSubArray(self, nums: List[int]) -> int:n = len(nums)ans = -inffor i, num in enumerate(nums):for j in range(i, n):sum_all = sum(nums[i: j + 1])if sum_all > ans:ans = sum_allreturn ans

但有个缺点:会超时 

2.算法>贪心算法

python">class Solution:def maxSubArray(self, nums: List[int]) -> int:n = len(nums)ans = -infcount = 0for i, num in enumerate(nums):count += numif count < num:count = numif count > ans:ans = countreturn ans

3.动态规划

python">class Solution:def maxSubArray(self, nums: List[int]) -> int:n = len(nums)dp = [-inf] * nans = dp[0] = nums[0]for i in range(1, n):dp[i] = max(dp[i - 1] + nums[i], nums[i])if dp[i] > ans:ans = dp[i]return ans

三、动态规划与算法>贪心算法的逻辑关系

仔细观察动态规划的递推公式dp[i] = max(dp[i - 1] +num, num)

dp[i - 1] +num和num的选择条件是是什么?

很明显是dp[i - 1]的值的正负号,与算法>贪心算法连续和为负时放弃连续和的条件完全吻合

因此,本题的关键就在于理解“连续”:

由于只能对连续子数组求和,

对于每一个数字,只需要在与上一个数字的连续和相加重新开始算连续和之间做出选择

不需要考虑当前数字与哪些数字求和能得到最大值

所以实际上对于本题而言:

动态规划解法就是算法>贪心算法的充分性证明,

算法>贪心算法就是动态规划的精简版

以下是算法>贪心算法到动态规划的一个过渡态写法:

python">class Solution:def maxSubArray(self, nums: List[int]) -> int:n = len(nums)ans = -infcount = 0for i, num in enumerate(nums):count += numif count < num:count = numif count > ans:ans = countreturn ans

注意相比与算法>贪心算法count的比较顺序是调换的


http://www.ppmy.cn/server/164777.html

相关文章

数据结构---线性表

线性表 顺序表 线性表的顺序存储结构是一种随机存取的存储结构&#xff0c;即通过首地址和元素序号可以在O(1)时间内找到指定的元素。由于线性表的长度可变&#xff0c;且所需最大存储空间随问题的不同而不同&#xff0c;在C/C中常用动态分配的一维数组(vector)表示线性表 代…

【人工智能学习笔记 一】 AI分层架构、基本概念分类与产品技术架构

新的一年2025要对AI以及LLM有个强化的学习&#xff0c;所以第一篇先对整体有个大概的认知&#xff0c;一直分不清LLM和AI的关系&#xff0c;在整个体系里的位置&#xff0c;以及AIGC是什么东西&#xff0c;AI AGENT类似豆包等和大语言模型的具体关系是什么&#xff0c;整个AI的…

实现智能教室能耗监测与管理系统的详细方案

以下是一个完整的实现智能教室能耗监测与管理系统的详细方案,涵盖深度学习模型研发、教室场景适应性分析、系统架构设计、前端展示、后端服务以及测试评估等方面,使用 Python 语言完成。 1. 深度学习模型研发 1.1 数据准备 首先,你需要收集大量的教室照片,并对其中的关键…

JavaScript 基础 - 7

关于JS函数部分的学习和一个案例的练习 1 函数封装 抽取相同部分代码封装 优点 提高代码复用性&#xff1a;封装好的函数可以在多个地方被重复调用&#xff0c;避免了重复编写相同的代码。例如&#xff0c;编写一个计算两个数之和的函数&#xff0c;在多个不同的计算场景中都…

解决MacOS安装软件时提示“打不开xxx软件,因为Apple无法检查其是否包含恶意软件”的问题

macOS 系统中如何开启“任何来源”以解决安装报错问题&#xff1f; 大家好&#xff01;今天我们来聊聊在使用 macOS 系统 时&#xff0c;遇到安装应用软件时出现报错的情况。这种情况常常发生在安装一些来自第三方开发者的应用时&#xff0c;因为 macOS 会默认阻止不明开发者的…

使用飞书群机器人监控服务器GPU使用率

目标&#xff1a;如果服务器GPU空置&#xff0c;可以及时推送消息到飞书群。 其他类似的监控目标也可以修改代码实现。 步骤&#xff1a; (1) 首先在群聊设置加入机器人&#xff0c;复制webhook_url (2) 在服务器后台运行如下代码。注意替换webhook_url """…

Java面试题2025-并发编程基础(多线程、锁、阻塞队列)

并发编程 一、线程的基础概念 一、基础概念 1.1 进程与线程A 什么是进程&#xff1f; 进程是指运行中的程序。 比如我们使用钉钉&#xff0c;浏览器&#xff0c;需要启动这个程序&#xff0c;操作系统会给这个程序分配一定的资源&#xff08;占用内存资源&#xff09;。 …

DeepSeek 云端部署,释放无限 AI 潜力!

1.简介 目前&#xff0c;OpenAI、Anthropic、Google 等公司的大型语言模型&#xff08;LLM&#xff09;已广泛应用于商业和私人领域。自 ChatGPT 推出以来&#xff0c;与 AI 的对话变得司空见惯&#xff0c;对我而言没有 LLM 几乎无法工作。 国产模型「DeepSeek-R1」的性能与…