动态规划
DarkFlameMaster2188
这个作者很懒,什么都没留下…
展开
-
647. 回文子串
情况三:下标:i 与 j相差大于1的时候,例如cabac,此时s[i]与s[j]已经相同了,我们看i到j区间是不是回文子串就看aba是不是回文就可以了,那么aba的区间就是 i+1 与 j-1区间,这个区间是不是回文就看dp[i + 1][j - 1]是否为true。的dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的子串是否是回文子串,如果是dp[i][j]为true,否则为false。回文字符串 是正着读和倒过来读一样的字符串。当s[i]与s[j]不相等,dp[i][j]一定是false。原创 2024-07-02 21:50:38 · 328 阅读 · 0 评论 -
72. 编辑距离
如果 (word1[i - 1] == word2[j - 1]) 那么说明不用任何编辑,dp[i][j] 就应该是 dp[i - 1][j - 1],即dp[i][j] = dp[i - 1][j - 1];dp[i][j] 表示以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][j]。增加一个字符,相当于word2删除一个字符,dp[i][j] = dp[i][j - 1] + 1;原创 2024-07-02 16:37:21 · 324 阅读 · 0 评论 -
115. 不同的子序列
从递推公式dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]和 dp[i][j] = dp[i - 1][j]中可以看出dp[i][j] 是从上方和左上方推导而来,那么 dp[i][0] 和dp[0][j]是一定要初始化的。当s[i - 1] 与 t[j - 1]不相等时,dp[i][j]只有一部分组成,不用s[i - 1]来匹配(就是模拟在s中删除这个元素),即:dp[i - 1][j],所以递推公式为:dp[i][j] = dp[i - 1][j]原创 2024-07-02 14:04:10 · 348 阅读 · 0 评论 -
392. 判断子序列
这里大家已经可以发现,在定义dp[i][j]含义的时候为什么要表示以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度为dp[i][j]。,t如果把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是 看s[i - 1]与 t[j - 2]的比较结果了,从递推公式可以看出dp[i][j]都是依赖于dp[i - 1][j - 1] 和 dp[i][j - 1],所以。,因为找到了一个相同的字符,相同子序列长度自然要在dp[i-1][j-1]的基础上加1。原创 2024-07-02 10:15:08 · 233 阅读 · 0 评论 -
53. 最大子数组和
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组是数组中的一个连续部分。一定是取最大的,所以dp[i] = max(dp[i - 1] + nums[i], nums[i]);dp[i]:包括下标i(以nums[i]为结尾)的最大连续子序列和为dp[i]dp[0]应为nums[0]即dp[0] = nums[0]原创 2024-07-02 09:23:31 · 184 阅读 · 0 评论 -
1143. 最长公共子序列
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。,那就看看text1[0, i - 2]与text2[0, j - 1]的最长公共子序列 和 text1[0, i - 1]与text2[0, j - 2]的最长公共子序列,取最大的。主要就是两大情况: text1[i - 1] 与 text2[j - 1]相同,text1[i - 1] 与 text2[j - 1]不相同。如果不存在 公共子序列 ,返回 0。原创 2024-07-01 16:25:53 · 179 阅读 · 0 评论 -
718. 最长重复子数组
dp[i][0] 和dp[0][j]要初始值,因为 为了方便递归公式dp[i][j] = dp[i - 1][j - 1] + 1;(特别注意: “以下标i - 1为结尾的A” 标明一定是 以A[i-1]为结尾的字符串,这样初始化方便 )给两个整数数组 nums1 和 nums2 ,返回 两个数组中 公共的 、长度最长的子数组的长度。根据dp[i][j]的定义,dp[i][j]的状态只能由dp[i - 1][j - 1]推导出来。,这样就比较好推 递推公式了。内外循环分别遍历两个数组就可以。原创 2024-07-01 15:54:29 · 132 阅读 · 0 评论 -
300. 最长递增子序列
例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。我们在做递增比较的时候,如果比较 nums[j] 和 nums[i] 的大小,那么两个递增子序列一定分别以nums[j]为结尾 和 nums[i]为结尾。j其实就是遍历0到i-1,那么是从前到后,还是从后到前遍历都无所谓,只要吧 0 到 i-1 的元素都遍历了就行了。所以默认习惯 从前向后遍历。子序列问题是动态规划解决的经典问题,当前下标i的递增子序列长度,其实和i之前的下表j的子序列长度有关系。原创 2024-07-01 09:23:42 · 280 阅读 · 0 评论 -
309. 买卖股票的最佳时机含冷冻期
我的思路是如果第i天保持股票持有状态,那么要么i-1天就持有股票,要么i-1未持有股票,今天购买:i-1天未持有股票要么是在冷冻期,要么是i-2天也没有股票,递推公式相当于dp[i][0] = max(dp[i - 1][0], dp[i - 2][1] - prices[i]);,即:dp[i][2] ,只有一个操作:昨天一定是持有股票状态(状态一),今天卖出,即:dp[i][2] = dp[i - 1][0] + prices[i];dp[i][j],第i天状态为j,所剩的最多现金为dp[i][j]原创 2024-06-30 16:37:11 · 356 阅读 · 0 评论 -
123. 买卖股票的最佳时机 III
第二次买入依赖于第一次卖出的状态,其实相当于第0天第一次买入了,第一次卖出了,然后再买入一次(第二次买入),所以第二次买入操作,初始化为:dp[0][3] = -prices[0];操作一:第i天卖出股票了,那么dp[i][2] = dp[i - 1][1] + prices[i]操作二:第i天没有操作,沿用前一天卖出股票的状态,即:dp[i][2] = dp[i - 1][2]操作一:第i天买入股票了,那么dp[i][1] = dp[i-1][0] - prices[i]3.第一次不持有股票。原创 2024-06-30 14:34:27 · 358 阅读 · 0 评论 -
121. 买卖股票的最佳时机
其基础都是要从dp[0][0]和dp[0][1]推导出来。那么dp[0][0]表示第0天持有股票,此时的持有股票就一定是买入股票了,因为不可能有前一天推出来,所以。,所得现金就是按照今天股票价格卖出后所得现金即:prices[i] + dp[i - 1][0],那么就保持现状,所得现金就是昨天不持有股票的所得现金 即:dp[i - 1][1],那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0]dp[0][1]表示第0天不持有股票,不持有股票那么现金就是0,所以。原创 2024-06-30 13:16:12 · 165 阅读 · 0 评论 -
337. 打家劫舍 III
一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。即:{不偷当前节点得到的最大金钱,偷当前节点得到的最大金钱}dp数组以及下标的含义:下标为0记录不偷该节点所得到的的最大金钱,下标为1记录偷该节点所得到的的最大金钱。本题的难点在于如何根据左右孩子的状态递推中间节点,求递推公式,并记录当前能够盗取的最高金额。题目:小偷又发现了一个新的可行窃的地区。我们要求是否盗取当前节点的最大金额,因此返回值是一个。(1)确定递归函数的参数和返回值(确定dp数组),因为需要通过左右孩子的状态,来。原创 2024-06-29 16:23:13 · 224 阅读 · 0 评论 -
213. 打家劫舍 II
同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,今晚能够偷窃到的最高金额。注意我这里用的是"考虑",而情况二 和 情况三 都包含了情况一了,所以只考虑情况二和情况三就可以了。题目:你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都。(2)考虑包含首元素,不包含尾元素。(3)考虑包含尾元素,不包含首元素。(1)考虑不包含首尾元素。原创 2024-06-29 11:00:49 · 202 阅读 · 0 评论 -
198. 打家劫舍
题目:你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。从dp[i]的定义上来讲,dp[0] 一定是 nums[0],dp[1]就是nums[0]和nums[1]的最大值即:dp[1] = max(nums[0], nums[1]),即:第i-1房一定是不考虑的,找出 下标i-2(包括i-2)以内的房屋,最多可以偷窃的金额为dp[i-2] 加上第i房间偷到的钱。原创 2024-06-29 09:18:30 · 310 阅读 · 0 评论 -
139. 单词拆分
如果确定dp[j] 是true,且 [j, i] 这个区间的子串出现在字典里,那么dp[i]一定是true。dp[i] 的状态依靠 dp[j]是否为true,那么dp[0]就是递推的根基,dp[0]一定要为true。本题也是完全背包问题,单词就是物品,字符串s就是背包,单词能否组成字符串s,就是问物品能不能把背包装满。本题要求组成字符串,是有顺序的,因此需要先遍历背包(字符串),再遍历物品(单词)注意:不要求字典中出现的单词全部都使用,并且字典中的单词。原创 2024-06-28 16:19:25 · 159 阅读 · 0 评论 -
279. 完全平方数
完全平方数是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。dp[0]表示 和为0的完全平方数的最小数量,那么。题目:给你一个整数 n ,返回。先遍历物品再遍历背包。原创 2024-06-28 15:07:04 · 211 阅读 · 0 评论 -
322. 零钱兑换
凑足总额为j - coins[i]的最少个数为dp[j - coins[i]],那么只需要加上一个钱币coins[i]即dp[j - coins[i]] + 1就是dp[j]考虑到递推公式的特性,dp[j]必须初始化为一个最大的数,否则就会在min(dp[j - coins[i]] + 1, dp[j])比较的过程中被初始值覆盖。本题和之前的完全背包组合问题的区别在于,本题需要的是元素最少的组合数,因此dp数组的定义以及初始化,还有递推公式与前面的组合问题不同。你可以认为每种硬币的数量是无限的。原创 2024-06-28 14:08:50 · 428 阅读 · 0 评论 -
377. 组合总和 Ⅳ
题目:给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target。请你从 nums 中找出并返回总和为 target 的元素组合的个数。题目数据保证答案符合 32 位整数范围。注意,本题会出现dp[i] + dp[i - nums[j]]大于INT_MAX的情况,因此在计算dp[i]时需要加一个判断条件。本题和零钱兑换问题的区别在于本题是排列问题,而零钱兑换是组合问题。两者在遍历顺序上有区别。原创 2024-06-28 10:16:44 · 138 阅读 · 0 评论 -
518. 零钱兑换 II
题目:给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。如果任何硬币组合都无法凑出总金额,返回 0。本题是完全背包理论的组合问题,和0-1背包的组合问题区别就是遍历顺序,背包体积要从weights[i]开始遍历。dp[0] = 1 有没有含义,其实既可以说凑成总金额0的货币组合数为1,也可以说凑成总金额0的货币组合数为0。求装满背包有几种方法,公式都是:dp[j] += dp[j - nums[i]]本题求的是组合,因此没有顺序,先遍历物品,再遍历背包。原创 2024-06-28 09:26:18 · 329 阅读 · 0 评论 -
474. 一和零
dp[i][j] 可以由前一个strs里的字符串推导出来,strs里的字符串有zeroNum个0,oneNum个1。dp[i][j] 就可以是 dp[i - zeroNum][j - oneNum] + 1。然后我们在遍历的过程中,取dp[i][j]的最大值。本题本题中strs 数组里的元素就是物品,每个物品都是一个(物品重量就是数组元素中1和0的个数)。题目:给你一个二进制字符串数组 strs 和两个整数 m 和 n。物品就是strs里的字符串,背包容量就是题目描述中的m和n,先正序物品,再倒序容量。原创 2024-06-27 16:35:38 · 281 阅读 · 0 评论 -
494. 目标和
因为dp[0]是在公式中一切递推结果的起源,如果dp[0]是0的话,递推结果将都是0。已经有一个1(nums[i]) 的话,有 dp[4]种方法 凑成 容量为5的背包。已经有一个2(nums[i]) 的话,有 dp[3]种方法 凑成 容量为5的背包。已经有一个3(nums[i]) 的话,有 dp[2]种方法 凑成 容量为5的背包。已经有一个4(nums[i]) 的话,有 dp[1]种方法 凑成 容量为5的背包。已经有一个5 (nums[i])的话,有 dp[0]种方法 凑成 容量为5的背包。原创 2024-06-27 15:56:31 · 264 阅读 · 0 评论 -
1049. 最后一块石头的重量 II
每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。dp[j]表示容量(这里说容量更形象,其实就是重量)为j的背包,最多可以背最大重量为dp[j]。= y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。如果没有石头剩下,就返回 0。物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒序遍历。因为重量都不会是负数,所以dp[j]都初始化为0就可以了。如果 x == y,那么两块石头都会被完全粉碎;原创 2024-06-26 15:46:39 · 167 阅读 · 0 评论 -
416. 分割等和子集
如果题目给的价值都是正整数那么非0下标都初始化为0就可以了,如果题目给的价值有负数,那么非0下标就要初始化为负无穷。本题,相当于背包里放入数值,那么物品i的重量是nums[i],其价值也是nums[i]。物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒序遍历。(3)背包如果正好装满,说明找到了总和为 sum / 2 的子集。本题中每一个元素的数值既是重量,也是价值。(2)背包要放入的商品(集合里的元素)本题可转化为0-1背包问题,因为。原创 2024-06-26 14:52:35 · 290 阅读 · 0 评论 -
动态规划:01背包理论基础(滚动数组)
dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j],那么dp[0]就应该是0,因为背包容量为0所背的物品的最大价值就是0。dp[j]可以通过dp[j - weight[i]]推导出来,dp[j - weight[i]]表示容量为j - weight[i]的背包所背的最大价值。因为对于二维dp,dp[i][j]都是通过上一层即dp[i - 1][j]计算而来,本层的dp[i][j]并不会被覆盖!dp[j]为 容量为j的背包所背的最大价值,那么如何推导dp[j]呢?此时dp[j]有两个选择,原创 2024-06-26 13:36:54 · 404 阅读 · 0 评论 -
96. 不同的二叉搜索树
从递归公式上来讲,dp[以j为头结点左子树节点数量] * dp[以j为头结点右子树节点数量] 中以j为头结点左子树节点数量为0,也需要dp[以j为头结点左子树节点数量] = 1。题目:给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?本题的关键点在于确定递推公式,由于二叉搜索树的性质,所以本题中拥有相同节点数的二叉树搜索树的数量是相同的。,首先遍历节点数i,再遍历i里面每一个数作为头结点的状态,用j来遍历。由于j从1开始,所以只需要初始化dp[0]即可。原创 2024-06-25 21:47:22 · 144 阅读 · 0 评论 -
343. 整数拆分
从1开始遍历到j,一个是j * (i - j) 直接相乘,一个是一个是j* dp[i - j],相当于是拆分(i - j)为多个值进行计算。dp[i] = max({dp[i], (i - j) * j, dp[i - j] * j}) (注意:代码中max函数为两者中选出较大的)dp[i] 是依靠 dp[i - j]的状态,所以遍历i一定是从前向后遍历,先有dp[i - j]再有dp[i]从题目和dp的定义来看,只需要初始化dp[2]为1即可,因为dp[0]和dp[1]都没有意义。原创 2024-06-25 16:51:18 · 351 阅读 · 0 评论 -
62. 不同路径
题目:一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。dp[i][0]一定都是1,因为从(0, 0)的位置到(i, 0)的路径只有一条,那么dp[0][j]也同理。dp[i][j] = dp[i - 1][j] + dp[i][j - 1],因为只能从这两个点过来。dp[i][j] :表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。(1)确定dp数组(dp table)以及下标的含义。(3)dp数组的初始化。(5)举例推导dp数组。原创 2024-06-25 14:48:18 · 152 阅读 · 0 评论 -
70. 爬楼梯
从dp[i]的定义可以看出,dp[i] 可以有两个方向推出来。首先是dp[i - 1],上i-1层楼梯,有dp[i - 1]种方法,那么再一步跳一个台阶不就是dp[i]了么。还有就是dp[i - 2],上i-2层楼梯,有dp[i - 2]种方法,那么再一步跳两个台阶不就是dp[i]了么。所以dp[i] = dp[i - 1] + dp[i - 2]你有多少种不同的方法可以爬到楼顶呢?从递推公式dp[i] = dp[i - 1] + dp[i - 2];dp[i]: 爬到第i层楼梯,有dp[i]种方法。原创 2024-06-25 10:31:37 · 162 阅读 · 0 评论