![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
动态规划
996冲冲冲
这个作者很懒,什么都没留下…
展开
-
leetcode139. 单词拆分
遍历整个字符串,转移方程就是当前i位置之前的所有的j, [j:i]是否能组成单词且j是否能被拆分。回溯算法,用一个哈希表记录当前的划分方法是否可以,由于相当于深度优先,如果返回了,说明这种划分方法不行,标记下来防止重复访问。dp定义为以当前位置i为结尾子串的是否能被拆分。动态规划,枚举当前位置之前的所有起点。原创 2023-03-05 11:36:59 · 58 阅读 · 0 评论 -
leetcode128. 最长连续序列
只找最左边的那个端点,找到之后统计最长能达到的长度,并且更新。只用更新端点的值是因为一段区间的中间点是都访问过的不会再取到。为了方便查找用哈希表存储数据。所以+1和-1只会遇到端点。原创 2023-02-27 17:11:17 · 114 阅读 · 0 评论 -
leetcode338. 比特位计数
如果是偶数,相当于左移了一位,就是末位多了一位0。如果是奇数,等于前面的偶数末位的0变成了1。原创 2023-02-26 19:23:48 · 93 阅读 · 0 评论 -
leetcode877. 石子游戏
如果甲拿nums[i],那么变成乙先手面对区间[i+1…j],这段区间内乙对甲的净胜分为dp[i+1][j];那么甲对乙的净胜分就应该是nums[i] - dp[i+1][j]。最终求的就是,甲先手面对区间[0…n-1]时,甲对乙的净胜分dp[0][n-1]是否>=0。如果甲拿nums[j],同理可得甲对乙的净胜分为是nums[j] - dp[i][j-1]。甲乙比赛,甲先手面对区间[i…j]时,dp[i][j]表示甲对乙的净胜分。甲先手面对区间[i…以上两种情况二者取大即可。原创 2023-02-22 15:53:41 · 53 阅读 · 0 评论 -
leetcode123. 买卖股票的最佳时机 III
dp定义为dp[i][k][0]第i天没有持股,恰好完成了k笔交易(卖出时算一笔交易完成)的情况下可以获得的最大利润。注意按照这个通解,由于定义的是恰好完成k笔交易在卖出时算交易完成,根据递推公式无法涉dp[i][0][1]dp[0][k>=1][0or1] 不合法,因为是第一天不可能进行过交易。所以这一步放在k的循环之外。原创 2023-02-14 20:32:51 · 55 阅读 · 0 评论 -
leetcode123. 买卖股票的最佳时机 IV
持有和非持有分别用两个变量。原创 2023-02-14 19:48:47 · 71 阅读 · 0 评论 -
leetcode714. 买卖股票的最佳时机含手续费
公式:res + [prices[i] - buy1(prices[j])]+ [prices[j] - buy0(prices[k] +fee)] 前面一项相当于第二次卖,后面一项相当于第一次卖。所以可以在卖出大于(购买+手续费)时,卖出但是更新购买费用,所以当后面如果遇到更大的时候相当于反悔了卖给最大的了。所以不能像之前一样遇到大于(购买+手续费)的就操作一次,因为这样在当前卖出取不到最大收益时会浪费一次两次手续费。我们要尽可能的在少花手续费的前提下而尽可能的多赚钱,其实是一致的。原创 2023-02-13 22:30:20 · 76 阅读 · 0 评论 -
leetcode309. 最佳买卖股票时机含冷冻期
dp[i][1] = max(dp[i-1][1],dp[i-2][0]-prices[i]) #上上轮没持有才能买,或者上一轮持有不卖。所以base case是dp[0][0] = 0 dp[0][1] = -price[i]dp定义为第i天是否持有股票的最大收益,由于存在冷静期买入要发生在前两天且不持有的状态下。还可以分成四种状态:根据是否冷冻,是否持有划分。原创 2023-02-13 21:48:52 · 298 阅读 · 0 评论 -
leetcode122. 买卖股票的最佳时机 II
转移方程: dp[i][0] = max(前一天就没持有,前一天持有了今天卖了)dp[i][1] = max(前一天就持有, 前一天没持有今天买了)无限次买卖可以只买上涨的时候,题目说同一天不准交易两次应该是不推荐这种解法。动态规划: dp定义为在第i天有无持有股票的最大收益。可以压缩一下优化空间复杂度。原创 2023-02-13 20:05:19 · 84 阅读 · 0 评论 -
leetcode121. 买卖股票的最佳时机
遍历数组记录答案的最大值就行,需要保证最小价格区间是[0:i-1]常规解法,用一个数记录最小购买价格,一个数记录答案。原创 2023-02-13 17:29:33 · 38 阅读 · 0 评论 -
leetcode337. 打家劫舍 III
还是两个思路dp定义1. 从当前节点开始可以抢劫到的符合条件的最大值。所以利用这一点按照定义一从顶向下可以利用递归的返回值,节省空间。定义2. 到当前节点为止可以抢劫到的符合条件的最大值。因为是树的问题,后序遍历可以从下往上传递信息。定义2,自底向上,递归上体现为先序。原创 2023-02-12 22:14:32 · 50 阅读 · 0 评论 -
leetcode213. 打家劫舍 II
【代码】leetcode213. 打家劫舍 II。原创 2023-02-12 21:13:32 · 64 阅读 · 0 评论 -
leetcode198. 打家劫舍
转移方程:对于每个房子1.抢2.不抢,抢下一个,只用考虑每个防止的当前状态,不用考虑他之前怎么做的选择。dp[i] = max(dp[i+1],dp[i+2]+nums[i]) 第一个是不抢,第二个是抢。也可以正着思考,dp定义为前i个房子最多可以抢多少钱。dp定义为从当前房子开始可以抢到的最多的钱。原创 2023-02-12 21:00:46 · 68 阅读 · 0 评论 -
leetcode486. 预测赢家
如果甲拿nums[i],那么变成乙先手面对区间[i+1…j],这段区间内乙对甲的净胜分为dp[i+1][j];那么甲对乙的净胜分就应该是nums[i] - dp[i+1][j]。最终求的就是,甲先手面对区间[0…n-1]时,甲对乙的净胜分dp[0][n-1]是否>=0。如果甲拿nums[j],同理可得甲对乙的净胜分为是nums[j] - dp[i][j-1]。甲乙比赛,甲先手面对区间[i…j]时,dp[i][j]表示甲对乙的净胜分。甲先手面对区间[i…dp不考虑先后手的区别。dp考虑先后手的区别。原创 2023-02-12 20:01:13 · 69 阅读 · 0 评论 -
leetcode312. 戳气球
其中dp(i,j)表示在区间(i,j)上的最优值,w(i,j)表示在转移时需要额外付出的代价,min也可以是max。指在一段区间上进行动态规划,一般做法是由长度较小的区间往长度较大的区间进行递推,最终得到整个区间的答案。注意在做推导时可以画图看一下状态转移的方向,如何根据base case得到答案。并且注意目标值位置和需要推导的区间。原创 2023-02-11 22:51:00 · 61 阅读 · 0 评论 -
leetcode887. 鸡蛋掉落
确定i层j个蛋的情况,我们首先扔一个蛋,在哪扔不确定,设为x :x[1:i]dp定义为i层j个蛋至少扔的次数。x层扔出去会有两种情况。原创 2023-02-11 21:07:06 · 58 阅读 · 0 评论 -
leetcode44. 通配符匹配
【代码】leetcode44. 通配符匹配。原创 2023-02-10 21:22:07 · 45 阅读 · 0 评论 -
leetcode10. 正则表达式匹配
【代码】leetcode10. 正则表达式匹配。原创 2023-02-10 19:50:32 · 50 阅读 · 0 评论 -
leetcode514. 自由之路
所以当前是一路走过来到这一轮所有可能位置的最小值,每一轮所有位置的最小值都保留了,所以成立。如果只保留一个最小的位置的话就不成立了,这里保留的是所有位置的最小值。上一轮所有轮盘可能位置,到下一轮所有轮盘的可能位置的最小值。原创 2023-02-10 15:59:00 · 108 阅读 · 0 评论 -
leetcode174. 地下城游戏
注意这题要反向思维,如果定义dp为到达i,j所需要的最小生命值的话是无法进行状态转移的,从前面的状态无法转移到后面。所以考虑从后往前的dp,定义dp为从i,j出发到达终点所需的最小生命值。第二种是改变base case 之前的一个状态,使其满足状态转移方程。注意base case的两种写法,一种是直接写出来再循环里要跳过。原创 2023-02-09 17:19:09 · 182 阅读 · 0 评论 -
leetcode1449. 数位成本和为目标值的最大数字
动态规划,定义dp为恰好满足j的最大正数。原创 2023-02-08 22:38:20 · 61 阅读 · 0 评论 -
leetcode518. 零钱兑换 II
先定义dp,再找base和转移。原创 2023-02-08 20:02:48 · 106 阅读 · 0 评论 -
leetcode1049. 最后一块石头的重量 II
【代码】leetcode1049. 最后一块石头的重量 II。原创 2023-02-08 15:50:23 · 54 阅读 · 0 评论 -
leetcode494. 目标和
【代码】leetcode494. 目标和。原创 2023-02-08 15:47:58 · 49 阅读 · 0 评论 -
leetcode474. 一和零
【代码】leetcode474. 一和零。原创 2023-02-08 15:24:08 · 38 阅读 · 0 评论 -
leetcode416. 分割等和子集
因为j的范围是[0,m],所以是m+1个数,n直接对应数组下标[0,n-1], 所以当dp[0][x]就是选择第一个下标为0的数。如果不选取任何正整数,则被选取的正整数等于 0。因此对于所有 0≤i原创 2023-02-04 16:28:59 · 55 阅读 · 0 评论 -
leetcode70. 爬楼梯
爬上n阶楼梯可以是n-1爬一阶和n-2爬两阶。所以结果等于他俩的和。原创 2023-02-03 21:28:05 · 54 阅读 · 0 评论 -
leetcode1312. 让字符串成为回文串的最少插入次数
扩散时相等不用插入,不相等选择小的那个插入1个。dp定义为i到j之间成为回文串的最小插入次数。base case单个字符是回文。原创 2023-02-03 20:37:17 · 55 阅读 · 0 评论 -
leetcode516. 最长回文子序列
如果两边的字符相等,那么最长回文子序列可以直接加入这两个字符。如果两边的字符不相等,那么最长回文子序列只能加入其中的一个。动态规划,重点还是找到base case和状态转移方程。转移方程:先分解问题,对于每个片段,我们将它向两边扩散。虽然这是一个字符串,但还是要用到二维的动态规划。那么易知base case:就是单个的字符。原创 2023-02-03 20:17:59 · 41 阅读 · 0 评论 -
leetcode712. 两个字符串的最小ASCII删除和
dp[i-1][j] + ord(s1[i-1]) 说明上往下移,也就是当前行的字符串被删除了,因为字符串的一位偏移,所以减去ord(s1[i-1])dp[i][j-1] + ord(s2[j-1]) 说明左往右移,也就是当前列的字符串被删除了。状态转移: 因为要考虑空串也就是base case的情况,所以会造成字符串一位的偏移。base:第0行和第0列。原创 2023-02-03 15:05:12 · 51 阅读 · 0 评论 -
leetcode583. 两个字符串的删除操作
最长公共子序列扩展,就数学计算一下。原创 2023-02-02 21:47:28 · 38 阅读 · 0 评论 -
leetcode1143. 最长公共子序列
定义dp是i,j之间的最长公共子序列长度。原创 2023-02-02 21:28:59 · 42 阅读 · 0 评论 -
leetcode53. 最大子数组和
动态规划,将dp定义为以num[i]结尾的最大子数组和,这是子序列或者子数组的常见做法。所以只有当窗口小于0时缩小窗口,这样遍历到所有以正数为开头的子数组了。滑窗,正确性在于最大子数组一定是以正数开头的或者是全负的最小负数。前缀和,注意前缀和有一位的偏移。这样转移方程显而易见了。原创 2023-02-02 17:29:49 · 72 阅读 · 0 评论 -
leetcode931. 下降路径最小和
状态转移记住有三个方向还有注意不要越界。原创 2023-02-01 16:02:14 · 39 阅读 · 0 评论 -
leetcode72. 编辑距离
和word2的0~j位置匹配,因此此时dp[i][j]=dp[i-1][j]+1(这个加1代表执行删除操作)(一)、当word1[i]==word2[j]时,由于遍历到了i和j,说明word1的0。由于当前两个字符相同,因此无需做任何操作,dp[i][j]=dp[i-1][j-1]所以此时dp[i][j]=dp[i-1][j-1]+1(这个加1代表执行替换操作)所以此时dp[i][j]=dp[i][j-1]+1(这个加1代表执行插入操作)需要在这三个操作中选取一个最小的值赋格当前的dp[i][j]原创 2023-02-01 14:53:11 · 128 阅读 · 0 评论 -
leetcode64. 最小路径和
两条边界和不在边界的情况,因为是在原数组上修改,所以都等于0时不需要改变。原创 2023-01-26 19:59:39 · 111 阅读 · 0 评论 -
leetcode354. 俄罗斯套娃信封问题
思路:因为不允许相同宽度或者长度的信封嵌套,所以可以先对长度进行升序排序,长度相同对宽度进行降序排序。之后再根据宽度计算最长子序列,这样就避免了相同的宽度或者长度嵌套。最后就是经典的计算最长子序列的方法了。动态规划计算最长子序列,超时。原创 2023-01-18 23:07:24 · 181 阅读 · 0 评论 -
leetcode300. 最长递增子序列
下面算法进行了简化,小的值直接覆盖在比它大的最左边的堆上,所以只用一个栈就可以完成了。二分法计算:具体思路参考耐心排序。做法是把这些数字分堆,规则是。原创 2023-01-18 15:22:23 · 41 阅读 · 0 评论 -
leetcode322. 零钱兑换
由于可能存在很多的重复计算,可以用一个count数组作为备忘录。对于给定的一个目标,我们自顶向下遍历所有可能。最后在所有可能里选择最小的那个。原创 2023-01-15 00:21:46 · 44 阅读 · 0 评论