- 博客(49)
- 收藏
- 关注
原创 leetcode动态规划—子序列系列
1、首先是子序列问题、子串问题、子数组问题,一定要搞清楚dp数组里是否是严格结尾2、其次是dp数组的定义,可以为了方便初始化而特殊处理定义一下。
2025-07-02 17:31:18
355
原创 《动手深度学习》8.2文本预处理—代码分析
这部分代码也让我头晕,想必大家也有很多问题,边写边查,边注释了~文本预处理的思路如下:1、读入文本2、数据清洗(去掉不要的符号、空格等)3、token化4、vocab词表化。
2025-06-04 18:43:17
263
原创 leetcode动态规划—买卖股票系列
可以多次买卖,买股票时,手头的现金不再是0,而是前一天的dp[i-1][0]要么从 第i-1天 ”不持有且非卖出状态“ 买入。要么从 第i-1天 持有继承。lc309 买卖股票的最佳时机+冷冻期。将不持有状态分为 卖出 \ 非卖出。把上述的2次交易,换成k次。2*2 + 1 个状态。2*k + 1个状态。卖出的时候扣除手续费。
2025-05-31 13:58:17
272
原创 leetcode动态规划—完全背包系列
分为三类1、求最值(最大价值、最小长度)——对应这的理论基础与lc322零钱兑换2、求组合——对应lc518零钱兑换3、求排列——对应lc377组合总和IV、lc57爬楼梯进阶遍历顺序:最值:可以颠倒,因为最后都是最值更新,不会重复计算组合组合:只能是先物品-后背包,否则会重复计算组合排列:只能是先背包-后物品,否则漏掉排列(排列问题一律看作爬楼梯。
2025-05-30 15:18:39
590
原创 leetcode 动态规划——01背包问题系列
与lc416分割等和子集基本一样尽可能分为两堆重量相近的石堆则以sum // 2为背包容量,石头重量==石头价值,求背包最大价值。
2025-05-23 20:41:31
315
原创 leetcode 动态规划经典题总结
代码随想录》动态规划五部曲:1、dp数组含义2、递推公式3、dp数组初始化4、遍历顺序5、打印dp数组调试。
2025-05-23 20:41:13
205
原创 leetcode37(hard)全网最易懂最全版本!!!!!—解数独
超时!!!!每次都两层for循环太慢,而且valid效率低,每次都要查找board。
2025-05-13 15:52:58
81
原创 leetcode51—N皇后(全网最易懂)
4、更新操作为“计数”,当计数为0时,该位置无攻击,当计数>0时,该位置有皇后攻击。1、一行作为一层递归,本层for循环代表着本行的皇后的每个可能位置。3、放入一个皇后时,更新visit数组,回溯时,也更新visi数组。2、用一个二维的visit数组存储皇后的攻击范围。
2025-05-12 22:50:27
186
原创 leetcode322(hard)—图论+回溯算法—重新安排行程
这题其实是经典构造的欧拉路径,题目已经明确说了,满足欧拉图的条件,因此我们用经典的hierholzer算法构造就好了还需要满足升序条件,那提前进行排序就行1、逆序排序,因为我们用pop,所以将最小的排在最后2、pop相当于删除一条有向边,保证了不重复走边3、构造欧拉路径的方式是回溯到当前层函数时,将当前层的from加入进路径,所以路径其实是反的4、最后记得逆序路径。
2025-05-12 19:07:38
112
原创 leetcode46\47回溯算法—全排列问题
对于排列问题,每层for循环都可以对整个nums数组做选择,但不能再选择已选择过的数(即一个数不能重复使用,但如果有多个相同数,是可以用上的)由此,舍去startindex,加入used数组,在每次选取的时候看看是否已经选过了由于used数组是多个递归函数共享的,所以要做回溯处理(back前后)
2025-05-12 15:54:39
179
原创 全网最易懂leetcode239.滑动窗口的最大值—单调队列
1、当一个元素num要加入队列时,从队列的右侧开始考察,把比num小的都pop了,因为num比他们更大,只要num加入进了队列,他们永远不可能成为最大值了。直观暴力解法:维护一个长度k的滑动窗口,遍历nums(长度为n),每次找窗口里的最大值,总复杂度为O(nk),k过大可能超时。2、达到条件开始收割答案、并且收缩窗口(注意,收缩时要看扔掉的是不是当前队头)维护一个单调递减的双端队列deque,队列头永远是当前的最大值。如此理解:队列里只存放当前窗口内,可能成为最大值的那些元素。
2025-04-29 23:24:04
416
原创 KMP算法——全网最通俗易懂!!!!!
写一下个人对KMP算法的看法1、我们在做字符串匹配问题时,用暴力方法来进行遍历是O(m*n)的,也就是每次不匹配时,模式串都回到开头,并往右移一位,模式串再次从开头进行匹配,而KMP算法解决的问题就是——不匹配时,是否能将模式串往后多移几位,并且模式串无需再从开头进行匹配,这样达到O(m+n)复杂度,也就是两个字符串都只遍历1次(模式串为常数次)2、如何做到?假设模式串和符号串当前对比的字符不匹配,那它俩之前的字符肯定是匹配成功了的。那我考查模式串这之前字符的最长相等前后缀。
2025-04-29 20:35:20
303
原创 leetcode.15、18——双指针的用法
首先想法——哈希表当然可以通过2层for循环得到sum的一部分,存到哈希表中,寻找target == 0 - sum但这种方法去重太繁琐利用双指针重点在于去重逻辑。
2025-04-28 22:13:45
392
原创 leetcode.206\24反转链表
难点在于,当我修改cur.next之后,我原链表没办法借助cur.next进行正常的迭代,所以需要temp来记录。
2025-04-28 15:40:44
116
原创 leetcode.数组滑动窗口209/904/76
其实滑动窗口就是变相的双指针,不停加入right达到“条件”后开始缩减窗口(移动left),打擂台挑出正确值。
2025-04-21 21:48:43
107
原创 leetcode.数组双指针27/26/283/844/977
明确快慢双指针含义快:寻找非val的元素慢:指向新数组下一个元素的位置(或者说新数组的长度)
2025-04-21 17:48:54
160
原创 leetcode.二分查找系列35/34/69/367/153
参考自“代码随想录”如果查找到,直接返回mid如果没查找到,最后的区间长度要么是1,要么是2如果区间是1,left == right == mid此时两种情况都是插入到left的位置如果区间是2,left == mid此时两种情况也是插入到left的位置所以如果没查找到,返回left还是去二分查找,分别找左、右边界,当查找到时:如果需要找右边界——修改left向右继续查找如果需要找左边界——修改right向左继续查找和lc35一样,只是返回right(向下取整,且不存在负数的情况,
2025-04-21 16:39:39
438
原创 排序算法总结
首先假定,当前节点,左孩子,右孩子中最大者为当前节点,然后将三者比较,得出最大者的下标,如果i不为最大者则,交换i与其值(对于长度为n的array,进行n轮比较(或n-1轮),每轮比较结束时,都会将最大的数冒泡到array尾部。对于长度为n的array,遍历到当前值时,认为之前的值都有序了,往前遍历找到插入位置(同时移动数组)(也就是j可能没正确指向比他小的值,而是指向>=pivot的值时刻,由于i==j跳出了循环)思想是选取一个值pivot,比pivot小的放左边,比pivot大的放右边,递归处理。
2025-04-21 13:04:24
509
原创 leetcode.131/93回溯算法—分割
startindex为分割开始的下标(left)i为分割结束的下标 (right)这俩中间夹的,就是目前分割出来的字符串,拿去判断是否为回文如果是回文,更新startindex为i+1,递归继续分割后面的剩余部分,如果不是回文,continue,考查for循环的下一个i+1。
2025-04-17 20:52:17
222
原创 leetcode236/235.二叉树最近公共祖先总结
所以对于这个236题,我第一反应直观的想法是求到根节点到p、q两个节点的path,然后逆向去求两条path的第一个相交节点(或是正向求得当两个节点的值不同的时候,那么前一个节点就是最近公共祖先)2:如果一个节点node的左子树有p or q,而右子树没有p or q,那公共祖先要么在node之上,要么就是身处node的左子树的p or q本身。1:如果一个节点node的左子树有p or q,右子树也有p or q,那node就是他俩的最近公共祖先。利用二叉搜索树的性质进行遍历就行,很简单没什么讲的。
2025-04-15 20:20:06
190
原创 leetcode98/530/501/538.二叉搜索树属性题型总结
其实你看见二叉搜索树,把它和中序遍历联系起来就好了,二叉搜索树结构成立 == 中序遍历有序,这两者之间有等价关系,为什么?因为l mid r的中序遍历顺序与二叉搜索树 左子树 < 中节点 < 右子树的结构性质吻合,这两者等价性的必要与充分我就不证明了,接下来放题目总结以及代码技巧。双指针遍历思想:定义一个pre代表前节点,不断更新pre。
2025-04-15 19:05:22
780
原创 leetcode.617合并二叉树
问题来了,那我们要在递归过程中记录父节点吗?并不可以这样 node1(左) = node2(右) 这样简单的节点赋值。,改变root指向node1的指针,例如node1是父节点的左孩子,那么。4、左节点存在,右节点存在,返回val叠加后的左节点。1、左节点None,右节点None,返回None。我们使用了返回值来达到修改结构的目的(向父节点返回子树根节点)2、左节点存在,右节点None,返回左节点。3、左节点None,右节点存在,返回右节点。,这样才算改变结构,把右子树挪过去了。
2025-04-14 21:47:54
136
原创 leetcode105+106.从中序和后序、中序和前序遍历序列构造二叉树
中序(l mid r),后序(l r mid),那么后序序列的最后一个=根节点,且中序序列中,在根节点数值左边的为左子树,根节点右边的为右子树。根据这个规律不断分割给出的序列就行。可以想一下,如果我只有后序+前序,我只能确定后序的last为根节点,前序的first为根节点,我找不到左右子树。因为只有中序才能把左子树和右子树分开,才能以此去分割序列。为啥没有后序+前序这个组合,非得有个中序?3python如果切片越界会返回空列表【】2理解递归函数的返回值为新建树的根节点。1注意分割的边界处理。
2025-04-14 16:36:19
310
原创 leetcode226.翻转二叉树
只需要注意,中序遍历不行,左中右的遍历顺序的话,先翻转了左子树,然后处理中节点的时候,把左右子树交换了,然后翻转右子树(但此时的右子树就是刚刚被翻转了的左子树),出错。所以前序,后序都可以。
2025-04-14 16:10:39
90
原创 leetcode257.二叉树的所有路径
参考自“代码随想录”这道题在leetcode是简单题,但是有很多递归的易错点需要理解,还是需要花一些功夫的。我用的是python来解决这些算法题,所以这道题的递归方法要结合python的语言特性,读者用c++或java的可以结合自己的语言特性进行理解题目思路很好想到,我从根节点开始遍历,每遍历到一个节点,就把它加入路径(先处理了当前遍历到的节点),如果它是叶子节点,就找到其中一条路径,存到结果里,如果它有孩子,继续向孩子遍历,直到遍历完整棵树。那么应该是什么遍历顺序——显然中左右,前序。
2025-04-14 14:57:52
229
原创 leetcode110.平衡二叉树
判断是否为平衡二叉树,其实就是给计算数的高度这个函数加一个判断逻辑,如果当前节点的左子树高度与右子树高度之差大于1,则返回false,否则正常返回高度。我们这里用-1来替代false。
2025-04-12 22:32:22
75
原创 leetcode222.完全二叉树节点个数
但这没有利用完全二叉树的性质,这里要区分满二叉树和完全二叉树(自己查定义)。从根节点往左走,得到最左深度maxDepthL,同理从根节点往右走,得到最右深度maxDepthR,如果maxDepthL == maxDepthR,那么就是一课满二叉树,直接计算返回,不然继续向下递归,总能得到满二叉树,这样可以不用遍历所有节点。首先最直观的想法,对于一个普通二叉树,我们想知道节点个数,递归得到:左子树节点数目 + 右子树节点数目 + 1(当前节点),返回给上层函数(告诉他爹,我这有这么多节点~)
2025-04-12 21:56:53
180
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人