<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[Kolbe_Huang的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/Kolbe_Huang</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; Kolbe_Huang]]></copyright><item><title><![CDATA[代码随想录算法训练营Day60 | 84. 柱状图中最大的矩形]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132776252</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132776252</guid><author>Kolbe_Huang</author><pubDate>Sat, 16 Sep 2023 14:03:30 +0800</pubDate><description><![CDATA[因为在接雨水中，如果不能够形成一个完整的谷，那么就不需要进行任何计算，也就是说单调递增、递减的数组本来就不该有任何计算结果。这个要求的变化加大了双指针的难度，所以优先讨论更加适用的单调栈解法。和上一题一样按行来计算矩形面积，对于固定的一列，需要这一列的高度、对应的左边界、对应的右边界。和接雨水一样，本题同样有双指针 + dp 的解法，但是这个解法的时间复杂度有些可疑。和接雨水相比，本题中的双指针 + dp 会更加复杂一些，因为要求的不再是。，dp 的递推变得很困难，我也不确定具体的复杂度。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day59 | 503. 下一个更大元素II | 42. 接雨水]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132757937</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132757937</guid><author>Kolbe_Huang</author><pubDate>Sat, 16 Sep 2023 13:54:52 +0800</pubDate><description><![CDATA[一方面，单调栈适用于寻找当前元素左侧/右侧的第一个更大元素值，和本题的“寻找谷地”有紧密的联系；另一方面，之前在思路中提到的是寻找“左侧/右侧的最大高度”，而不是第一个更大元素，这似乎又没有很紧密的关系。计算，就需要找到这一行（一个谷内的行，不是传统意义上的一行）的起始位置。暴力解法中有大量的重复计算：在计算每一列作为谷底的时候，都要进行一次遍历来得到左侧的最大高度和右侧的最大高度。其中高需要列的值，宽需要列的下标，既然通过下标可以直接获取值，栈内只需要记录下标即可。实际的记录过程有点类似于简单的 dp。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day58 | 单调栈 | 739. 每日温度 | 496. 下一个更大元素 I]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132757926</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132757926</guid><author>Kolbe_Huang</author><pubDate>Sun, 10 Sep 2023 15:02:37 +0800</pubDate><description><![CDATA[在遍历到当前元素的时候，需要把当前元素和栈口的元素进行比较，从而得到当前元素的某些性质。由于只能比较当前元素和栈口元素，所以对栈内的元素性质有要求：（从 stack top 到 stack bottom）单调增或者单调减。单调栈的意义是帮助我们存放已经遍历过的元素，从而能够比较当前元素和之前遍历过的元素（其实只能和栈口的元素比较，所以需要栈内保持。单调栈的本质是空间换时间，用一个栈来记录遍历过的元素，但只需要遍历一边即可。注意，答案中比较的是元素的值，但是栈中维护的只是下标，使用的时候不要搞混。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day57 | 647. 回文子串 | 516. 最长回文子序列 | 动态规划总结篇]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132757908</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132757908</guid><author>Kolbe_Huang</author><pubDate>Sat, 09 Sep 2023 15:52:15 +0800</pubDate><description><![CDATA[动态规划总结。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day56 | 583. 两个字符串的删除操作 | 72. 编辑距离 | 编辑距离总结篇]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132757889</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132757889</guid><author>Kolbe_Huang</author><pubDate>Sat, 09 Sep 2023 13:03:35 +0800</pubDate><description><![CDATA[编辑距离总结在之前的讲解中，或多或少提到了编辑距离。那些题目或多或少都有一些别的解法，或者看作是重复字数组、重复子序列的变种。但是，实际上他们都能被看作是编辑距离判断子序列可以看作：只允许删除t的元素的情况下能否得到s不同的子序列可以看作：有多少种删除t的元素的方法能够得到s两个字符串的删除操作可以看作：允许删除两个字符串的元素，使其相同所需要的最少操作数编辑距离就是真正的编辑距离。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day55 | 392. 判断子序列 | 115. 不同的子序列]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132669877</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132669877</guid><author>Kolbe_Huang</author><pubDate>Sat, 09 Sep 2023 05:22:41 +0800</pubDate><description><![CDATA[但实际上，这是一道特殊版本的最长公共子序列，同时也是编辑距离的入门。看到多少种方法 + 子序列，第一反应是回溯所有的子序列，然而数据量很明显不可能支持回溯，题目难度也没有到必须暴力搜索的地步。题目要求判断 s 是否是 t 的子序列，其实相当于要求 s 和 t 的最大公共子序列的长度就是。dp 数组的初始化：对于当前的定义，初始化和之前是一样的，都是针对第一行和第一列进行单独的初始化。dp 数组的初始化：根据递推公式的要求，还是要初始化第一行和第一列。的递推公式进行了很长的讨论。的含义是反的，但不影响解题。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day53 | 1143. 最长公共子序列 | 1035. 不相交的线 | 53. 最大子序和 （动态规划）]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132649838</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132649838</guid><author>Kolbe_Huang</author><pubDate>Fri, 08 Sep 2023 14:58:58 +0800</pubDate><description><![CDATA[经过上述抽象化，可以发现，本题说是求绘制的最大连线数，其实就是求两个字符串的最长公共子序列的长度！来自代码随想录：直线不能相交，这就是说明在字符串 A 中找到一个与字符串 B 相同的子序列，且这个子序列不能改变相对顺序：只要相对顺序不改变，链接相同数字的直线就不会相交。虽然是一道一维的子序列，但还是很好体现了 dp 利用当前元素递推子问题的特性。的比较来得到正确的递推公式（dp 数组的定义还是比较好想的）。注意，由于这里的 dp 数组定义发生了变化，最终的结果一定是。，这样就可以直接使用之前的。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day52 | 300. 最长递增子序列 | 674. 最长连续递增序列 | 718. 最长重复子数组]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132614477</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132614477</guid><author>Kolbe_Huang</author><pubDate>Mon, 04 Sep 2023 15:09:17 +0800</pubDate><description><![CDATA[作为 dp 的序列第一题，难度不高，最大的难点在于找到正确的 dp 数组定义。一些思路的小提示：之前两题的定义都是需要以当前元素结尾的最大子序列长度，而本题有两个输入数组，所以使用二维数组来定义 dp 似乎也很合理。由于需要保持之前的状态，滚动数组的解需要内层遍历从后向前进行。本题问的是子序列，定义为“由数组派生而来的序列，删除（或不删除）数组中的元素而不改变其余元素的顺序”。dp 的遍历顺序：从小到大即可，由于只需要左上角的元素进行过初始化，两层循环的嵌套也就无所谓内外顺序。的最长重复子序列的长度。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day51 | 309. 最佳买卖股票时机含冷冻期 | 714. 买卖股票的最佳时机含手续费 | 股票总结]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132614473</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132614473</guid><author>Kolbe_Huang</author><pubDate>Sun, 03 Sep 2023 14:00:41 +0800</pubDate><description><![CDATA[股票问题总结股票问题是第一次在 dp 中需要记录状态的题型。之前的 dp 题，无论是打家劫舍还是背包问题，都是考验对子问题最优解的利用，即正确的递推公式+遍历顺序。股票问题则需要对子问题进行分类讨论，记录各个状态下的子问题最优解，这一点是非常新颖的。同时，不知道是不是巧合，大部分股票问题都可以用贪心来解决，虽然实现贪心的难度不小。最标准的股票问题应该是122. 买卖股票的最佳时机II，需要真正地记录并利用状态。随后，复杂的限制交易次数的股票问题188.买卖股票的最佳时机IV。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day50 | 123. 买卖股票的最佳时机III | 188. 买卖股票的最佳时机IV]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132578705</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132578705</guid><author>Kolbe_Huang</author><pubDate>Fri, 01 Sep 2023 12:49:06 +0800</pubDate><description><![CDATA[本题比之前两题难很多，之前的题目确定了“买卖一次”或者“无限买卖”，而本题规定的是“最多买卖两次”，也就是说可以买卖一次、买卖两次、完全不进行买卖，显得非常复杂。，因为如果进行一次买卖就能获得最大净利润，那么总可以在最后一天进行一次（无意义）的买入+卖出。的四个值中取最大值。在之前的题中，已经解释过，想要受益最大，最后一天必然需要将股票卖出。本题总让我觉得跟多重背包有点类似，就是在原题的基础上进行了升维处理，但是题目的含义没有改变。的三维数组，但本质上是一样的，无非就是在内部遍历时多加了一个遍历。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day49 | 121. 买卖股票的最佳时机 | 122. 买卖股票的最佳时机II]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132560608</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132560608</guid><author>Kolbe_Huang</author><pubDate>Fri, 01 Sep 2023 12:08:58 +0800</pubDate><description><![CDATA[的：当前能否卖出股票取决于之前是否持有股票，只记录之前得到的最大收益就无从得知对于股票的持有状态。dp 数组的初始化：从递推公式可知，我们需要初始化第一天的 dp 数组，其余值设为 0 即可（可以处理股票价格一直下跌的状态）本题的条件和上一唯一的不同在于股票可以多次买卖了（但是同时只能持有一支股票），其余条件都一样，甚至于本题也有一种贪心解法。本题只能买卖一次股票，也就是找最大的前后差：找到左边最小的，找到右边最大的，得到的最大非负差值就是最大利润。的滚动数组即可，依靠天数 i 对 2 的取余即可。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day48 | 198. 打家劫舍 | 213. 打家劫舍II | 337. 打家劫舍III]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132560544</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132560544</guid><author>Kolbe_Huang</author><pubDate>Wed, 30 Aug 2023 16:31:55 +0800</pubDate><description><![CDATA[很明显，暴力递归对子问题的重复计算导致了超时，所以我们希望使用 dp 来记录已经得到的子问题的最优解，不断递归来得到全局的最优解。和上一题的区别在于首尾元素也是相邻的，所以按照上一题的逻辑推到最后一栋房屋时，实际上不能自由根据收益选择是否要抢，还依赖于第一栋房屋的状态。但是递归超高的时间复杂度，导致超时，因为递归中有大量的重复计算。对于 dp 来说，二叉树的递归性质反而决定了题目更简单，因为递归只允许返回当前节点的状态。同样，其实也不需要保存每一个访问过的房屋的状态，直接记录最佳解即可。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day46 | 139.单词拆分 | 多重背包 | 背包问题总结]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132560469</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132560469</guid><author>Kolbe_Huang</author><pubDate>Wed, 30 Aug 2023 11:11:57 +0800</pubDate><description><![CDATA[理论基础通过之前这一堆背包问题的练习，解决背包问题已经比较有套路了，对遍历顺序、初始化的理解也算不错。然而，将复杂的问题背景抽象成背包问题，仍然是需要经过思考的，其中最后一块石头的重量 II、目标和绝对是这种复杂抽象的难题。另外，很多背包问题看上去也都能用回溯算法解决，但毫无疑问都一定会超时。区别在于，背包问题依然能够依靠子问题的解来节省复杂度，而回溯算法不可避免地需要进行穷举，只不过是优雅的穷举，两者还是有本质上的区别。代码随想录上总结了不同的递推公式。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day45 | 70. 爬楼梯 (进阶) | 322. 零钱兑换 | 279. 完全平方数]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132493297</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132493297</guid><author>Kolbe_Huang</author><pubDate>Tue, 29 Aug 2023 14:15:28 +0800</pubDate><description><![CDATA[看作是物品，n 看作是背包容量的话，就又是一道标准的完全背包问题：求填满背包使用的最少物品数。本题中的物品就是可以行走的步数 [1, 2]，重量是 n，可以重复选取步数，求走到第 n 层有多少种走法。如上所述，本题只要求满足金额的硬币数，不在意满足金额的结果的顺序，所以物品、背包的遍历顺序都可以。本题看上去是个简单的爬楼梯，但实际上是个简单的完全背包，重要的是可以考验对物品和背包的遍历顺序的理解。dp 的遍历顺序：由于不需要排列，二维数组可以解决，物品和背包的顺序无所谓。以完全背包的思路来解题，正如。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day44 | 完全背包 | 518. 零钱兑换 II | 377. 组合总和 Ⅳ | 完全背包小总结]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132473275</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132473275</guid><author>Kolbe_Huang</author><pubDate>Mon, 28 Aug 2023 13:32:50 +0800</pubDate><description><![CDATA[在求装满背包有几种方案的时候，认清遍历顺序是非常关键的；在先物品后背包时，当进行物品 i 对背包容量的更新时，物品 i+1 肯定不会出现在当前的结果中，也就是说在得到的结果中，物品 i+1 一定会出现在物品 i 的后面，顺序被固定了。e.g. 只会出现，绝不会出现在先背包后物品时，会在大小为 j 的背包内选取所有物品的可行结果，然后对大小为 j+1 的背包进行选取，所以物品出现的顺序是不固定的。e.g. 可能会出现和。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day43 | 1049. 最后一块石头的重量 II | 494. 目标和* | 474. 一和零]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132441934</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132441934</guid><author>Kolbe_Huang</author><pubDate>Mon, 28 Aug 2023 06:37:15 +0800</pubDate><description><![CDATA[题目链接理论基础题目描述比较复杂，但还是可以抽象化成 01 背包的变种：由于重量不相等的石头碰撞后还会留下差值的石头，所以只要将所有的石头分成两组，并希望两组石头的总重量之差接近 0 即可。抽象后的题意：给定石头stones，从中选出一部分石头，其总重量尽可能接近所有石头的总重量的一半。此时这就是 01 背包的一个变种：尽可能填满背包。分割总和子集：能不能装满背包最后一块石头II：尽可能装满背包目标和：装满背包有多少种方法一和零：尽力装满背包有多少物品。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day41 | 343. 整数拆分 | 96. 不同的二叉搜索树]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132426685</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132426685</guid><author>Kolbe_Huang</author><pubDate>Thu, 24 Aug 2023 14:14:55 +0800</pubDate><description><![CDATA[由于 BST 的性质，对于 i+1 来说，可以从 [1, i] 中任取 [1, k] 组成 BST，然后将 i+1 作为这个 BST 的最右叶子节点，然后将 [k+1, i] 组成的 BST 作为 i+1 的左子节点。但实际上，题目给的例子已经很好地展示了这个关系。最直观的想法是，对于 [1, i] 的数字组成的 BST，i+1 总是能成为这个 BST 的最右叶子节点和根节点的（右侧）父节点。的情况还有一种，3 是 1 的右子节点，2 是 3 的左子节点，这个似乎是个例外，所以之前的关系还需要再拓展。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day42 | 01背包理论基础 | 01背包 (滚动数组) | 416. 分割等和子集]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132426747</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132426747</guid><author>Kolbe_Huang</author><pubDate>Thu, 24 Aug 2023 09:36:53 +0800</pubDate><description><![CDATA[以上总结了两种01背包的解法：二维数组在清楚定义的情况下，更为简单明了，收到的限制也更少，但空间复杂度较高；一维滚动数组思路巧妙，需要特定的遍历顺序（内外层、倒序），但有超低的空间复杂度，代码简洁。其中的难点（思维点）在于不同维度的遍历顺序同一纬度的前后遍历顺序不同的递推公式初始化逻辑只有明白不同方法中以上难点的回答，才能真正理解01背包！]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day39 | 62. 不同路径 | 63. 不同路径 II]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132388290</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132388290</guid><author>Kolbe_Huang</author><pubDate>Wed, 23 Aug 2023 04:19:18 +0800</pubDate><description><![CDATA[另外，图论中的深度搜索似乎也可以完成：将路径看成二叉树的话，遍历所有的叶子节点即可。要注意，计算组合的时候不能直接计算分子、分母然后相除，而是要在计算分子时不断除以分母，防止溢出。，所以会直接超时，因为其中绝大部分的遍历都是没有意义的。本题的初始化中，“障碍之后的位置无法到达”也是个坑。步是向下走的，所以所有路径的总数是。本题可以用数论直接分析出结果：对于。]]></description><category></category></item><item><title><![CDATA[代码随想录算法训练营Day38 | 理论基础 | 509. 斐波那契数 | 70. 爬楼梯 | 746. 使用最小花费爬楼梯]]></title><link>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132360197</link><guid>https://blog.youkuaiyun.com/Kolbe_Huang/article/details/132360197</guid><author>Kolbe_Huang</author><pubDate>Wed, 23 Aug 2023 03:45:53 +0800</pubDate><description><![CDATA[另外，本题一个变种就是如果每一步能够爬 m 阶（本题 m=2），那么有多少种解法。区别只是在每一层内部加一个 for loop 循环。本题是非常基础的 dp，主要是熟悉 dp 五部曲的方法论。作为基础的 dp，维护整个 dp 数组有些昂贵了，只需要维护前两个值即可。可以理解为离开第 i 层（向上爬 1 或 2 阶）所需要的代价。那这就是一个考察点了，对。一定要初始化为1，此时可能候选人就要强行给。本题的题目描述有些令人费解。，使用动态规划是最有效的。，就可以发难了：为什么。的定义理解的不深入。]]></description><category></category></item></channel></rss>