- 博客(512)
- 收藏
- 关注
原创 63. 不同路径 II
本题是62.不同路径的障碍版,整体思路大体一致。但就算是做过62.不同路径,在做本题也会有感觉遇到障碍无从下手。其实只要考虑到,遇到障碍dp[i][j]保持0就可以了。也有一些小细节,例如:初始化的部分,很容易忽略了障碍之后应该都是0的情况。
2024-10-05 01:25:49 270
原创 746. 使用最小花费爬楼梯
大家可以发现这道题目相对于70.爬楼梯又难了一点,但整体思路是一样的。从509.斐波那契数到70.爬楼梯再到这道题目,大家感受到循序渐进的梯度了嘛。每个专题最开始的题目都有点简单,其实都是有目的性的,就是用简单题练习方法论,然后难度都是梯度上来的,一环扣一环。
2024-10-04 22:44:53 663
原创 70. 爬楼梯
这道题目和509.斐波那契数题目基本是一样的,但是会发现本题相比509.斐波那契数难多了,为什么呢?关键是:509.斐波那契数题目描述就已经把动规五部曲里的递归公式和如何初始化都给出来了,剩下几部曲也自然而然的推出来了。而本题,就需要逐个分析了,大家现在应该初步感受出动规五部曲的重要性了。简单题是用来掌握方法论的,例如昨天斐波那契的题目够简单了吧,但昨天和今天可以使用一套方法分析出来的,这就是方法论!
2024-10-04 21:56:47 361
原创 509. 斐波那契数
斐波那契数列这道题目是非常基础的题目,我在后面的动态规划的讲解中将会多次提到斐波那契数列!这里我严格按照动规五部曲来分析了这道题目,一些分析步骤有同学感觉没有必要搞的这么复杂,代码其实上来就可以撸出来。但我还是强调一下,简单题是用来掌握方法论的,动规五部曲将在接下来的动态规划讲解中发挥重要作用,敬请期待!
2024-10-04 21:27:04 413
原创 动态规划理论基础
动态规划,简称DP如果某一问题有很多重叠子问题,使用动态规划是最有效的。所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的,举一个经典的背包问题例子对比下动态规划和贪心算法的区别:例如:有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i]。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。动态规划中,假设dp[j]表示背包装j重量的物品时得到的最大价值,dp[j]是由。
2024-10-04 20:53:52 599
原创 455. 分发饼干
这道题是贪心很好的一道入门题目,思路还是比较容易想到的。文中详细介绍了思考的过程,想清楚局部最优,想清楚全局最优,感觉局部最优是可以推出全局最优,并想不出反例,那么就试一试贪心。
2024-10-04 16:28:44 262
原创 贪心算法理论基础
贪心的本质是选择每一阶段的局部最优,从而达到全局最优。这么说有点抽象,来举一个例子:例如: 有一堆钞票,你可以拿走十张,如果想达到最大的金额,你要怎么拿?指定每次拿最大的,最终结果就是拿走最大数额的钱。每次拿最大的就是局部最优,最后拿走最大数额的钱就是推出全局最优。再举一个例子: 如果是有一堆盒子,你有一个背包体积为n,如何把背包尽可能装满,如果还每次选最大的盒子,就不行了。这时候就需要动态规划。动态规划的问题在下一个系列会详细讲解。本篇给出了什么是贪心以及大家关心的贪心算法固定套路。
2024-10-04 15:48:10 197
原创 2、项目配置设计(上)
配置文件作用:把需要经常修改的参数,从代码中分离出来,单独管理,方便后期维护。开发一个web应用,肯定需要一些基础性的配置信息,这些信息项目中一般都会使用配置文件统一管理。图中只是一个简单的示意,随着我们项目的不断完善,后续该配置文件的信息也会越来越多,这里先简单介绍一下。HTTP模块:启动的端口号是多少。日志模块:日志级别、输出位置、日志文件名、是否打印堆栈信息,日志格式等。DB:连接地址和端口号、数据库名称、用户名和密码等。实际工作中,这些配置信息我们会从代码当中分离出来。
2024-10-04 01:46:24 349
原创 37. 解数独
解数独可以说是非常难的题目了,如果还一直停留在单层递归的逻辑中,这道题目可以让大家瞬间崩溃。所以我在开篇就提到了二维递归,希望可以帮助大家理解解数独的搜索过程。总结二维递归的套路:遍历二维切片的每个位置,尝试将可选项中的每一项放入当前位置,递归下去,直到二维切片所有位置都遍历完成。代入本题就是:遍历整个二维切片board的每个位置,在每个空白处尝试从[‘1’~‘9’] 9个字符中选一个符合条件的字符填充,然后向下递归。一波分析之后,再看代码会发现其实也不难,唯一难点就是理解二维递归的思维逻辑。
2024-10-03 19:29:12 749
原创 51. N 皇后
本题是我们解决棋盘问题的第一道题目。如果从来没有接触过N皇后问题的同学看着这样的题会感觉无从下手,可能知道要用回溯法,但也不知道该怎么去搜。这里我明确给出了棋盘的宽度就是for循环的长度(列数),递归的深度就是棋盘的高度(行数),这样就可以套进回溯法的模板里了。大家可以在仔细体会体会!
2024-10-03 17:38:53 754
原创 47. 全排列 II
continue;continue;都是可以的,这也是很多同学做这道题目困惑的地方,知道!也行而也行,但是就想不明白为啥。所以我通过举[1,1,1]的例子,把这两个去重的逻辑分别抽象成树形结构,大家可以一目了然:为什么两种写法都可以以及哪一种效率更高!这里可能大家又有疑惑,既然!也行而也行,那为什么还要写这个条件呢?直接这样写 不就完事了?continue其实并不行,一定要加上!或者,因为要一直是true或者一直是false才可以,而不是 一会是true一会又是false。所以这个条件要写上。
2024-10-03 16:03:31 541
原创 46. 全排列
每层都是从0开始搜索而不是startIndex需要used数组记录path里都放了哪些元素了排列问题是回溯算法解决的经典题目,大家可以好好体会体会。
2024-10-03 00:59:15 496
原创 491. 递增子序列
本题题解清一色都说是深度优先搜索,但我更倾向于说它用回溯法,而且本题我也是完全使用回溯法的逻辑来分析的。相信大家在本题中处处都能看到是回溯算法:求90.子集II的身影,但处处又都是陷阱。对于养成思维定式或者套模板套嗨了的同学,这道题起到了很好的警醒作用。更重要的是拓展了大家的思路!
2024-10-03 00:31:45 821
原创 78. 子集
相信大家经过了77. 组合【含回溯详解、N叉树类比、剪枝优化】216.组合总和III17.电话号码的字母组合22. 括号生成39.组合总和40.组合总和II131.分割回文串93.复原IP地址洗礼之后,发现子集问题还真的有点简单了,其实这就是一道标准的模板题。但是要清楚子集问题和组合问题、分割问题的的区别,子集是收集树形结构中树的所有节点的结果。而组合问题、分割问题是收集树形结构中叶子节点的结果。
2024-10-02 19:37:38 544
原创 93. 复原 IP 地址
在131.分割回文串中我列举的分割字符串的难点,本题都覆盖了。此外,合法性判断难度大一点,以及增加了剪枝和递归终止时能否收集结果的判断,可以说是131.分割回文串的加强版。在本文的树形结构图中,我已经把详细的分析思路都画了出来,相信大家看了之后一定会思路清晰不少!
2024-10-02 18:48:31 1091
原创 131. 分割回文串
这道题目在leetcode上是中等,但可以说是hard的题目了,但是代码其实就是按照模板的样子来的。那么难究竟难在什么地方呢?切割问题可以抽象为组合问题如何模拟那些切割线切割问题中递归如何终止在递归循环中如何截取子串如何判断回文我们平时在做难题的时候,总结出来难究竟难在哪里也是一种需要锻炼的能力。一些同学可能遇到题目比较难,但是不知道题目难在哪里,反正就是很难。其实这样还是思维不够清晰,这种总结的能力需要多接触多锻炼。
2024-10-02 17:42:11 1124
原创 40. 组合总和 II
本题同样是求组合总和,但就是因为其数组candidates有重复元素,而要求不能有重复的组合,所以相对于39.组合总和难度提升了不少。关键是去重的逻辑,代码很简单,网上一搜一大把,但几乎没有能把这块代码含义讲明白的,基本都是给出代码,然后说这就是去重了,究竟怎么个去重法也是模棱两可。所以本文有必要把去重这块彻彻底底的给大家讲清楚,就连“树层去重”和“树枝去重”实际不是业界词汇,这么描述是希望对大家理解有帮助!
2024-10-02 16:11:58 611
原创 39. 组合总和
本题和我们之前讲过的77.组合、216.组合总和III组合没有数量要求元素可无限重复选取针对这两个问题,我都做了详细的分析。并且给出了对于组合问题,什么时候用startIndex,什么时候不用,并用17.电话号码的字母组合做了对比。最后还给出了本题的剪枝优化,这个优化如果是初学者的话并不容易想到。在求和问题中,排序之后加剪枝是常见的套路!可以看出写的文章都会大量引用之前的文章,就是要不断作对比,分析其差异,然后给出代码解决的方法,这样才能彻底理解题目的本质与难点。
2024-10-02 14:24:42 1042
原创 22. 括号生成
对于括号相关问题,有一条定论:已经出现的左括号一定比右括号多才可能是合法的括号,所以总共就只能使用"(“和”)“,如果想要最终的括号是有效的,那么当前节点剩余的”)“一定要比”("多。中选出一个括号,根据所选括号是左括号还是右括号,相应的括号计数就减一,左右括号计数都归零时,便是一条符合结果的路径。,即将所有的括号选完,当然,代码中我们做了剪枝(同时也是拦截不符合条件的路径,也是递归终止条件)这题是经典的回溯题,但其实网上很多解法说的都比较绕,比如下面的解法。是有的,还是归功于我们的回溯法模版。
2024-10-02 01:37:49 412
原创 17. 电话号码的字母组合
本篇将题目的三个要点一一列出,并重点强调了和前面讲解过的77. 组合 和216.组合总和III的区别,本题是多个集合求组合,所以在回溯的搜索过程中,都有一些细节需要注意的。其实本题不算难,但也处处是细节,大家还要自己亲自动手写一写。
2024-10-01 23:03:13 704
原创 216. 组合总和 III
开篇就介绍了本题与77.组合的区别,相对来说加了元素总和的限制,如果做完77.组合再做本题在合适不过。分析完区别,依然把问题抽象为树形结构,按照回溯三部曲进行讲解,最后给出剪枝的优化。相信做完本题,大家对组合问题应该有初步了解了。
2024-10-01 22:18:22 998
原创 77. 组合【含回溯详解、N叉树类比、剪枝优化】
组合问题是回溯法解决的经典问题,我们开始的时候给大家列举一个很形象的例子,就是n为100k为50的话,直接想法就需要50层for循环。从而引出了回溯法就是解决这种k层for循环嵌套的问题。然后进一步把回溯法的搜索过程抽象为树形结构,可以直观的看出搜索的过程。接着用回溯法三部曲,逐步分析了函数参数、终止条件和单层搜索的过程。本篇我们对求组合问题的回溯法代码做了剪枝优化,这个优化如果不画图的话,其实不好理解,也不好讲清楚。
2024-10-01 19:11:40 888
原创 回溯算法理论基础
回溯法也可以叫做回溯搜索法,它是一种搜索的方式。257. 二叉树的所有路径(回溯详解)回溯是递归的副产品,只要有递归就会有回溯。所以以下讲解中,回溯函数也就是递归函数,指的都是一个函数。本篇我们讲解了,什么是回溯算法,知道了回溯和递归是相辅相成的。接着提到了回溯法的效率,回溯法其实就是暴力查找,并不是什么高效的算法。然后列出了回溯法可以解决几类问题,可以看出每一类问题都不简单。最后我们讲到回溯法解决的问题都可以抽象为树形结构(N叉树),并给出了回溯法的模板。
2024-10-01 17:48:07 1345
原创 二叉树:总结篇!【需要掌握的二叉树技能都在这里啦】
不知不觉二叉树专题已经刷了30多道经典题目。在每一道二叉树的题目中,我们都使用了递归三部曲1. 返回值、参数是什么?2. 终止条件是什么?3. 单层逻辑是什么?下面我们把分析过的题目分门别类,可以帮助大家循序渐进学习二叉树,也方便快速复习,看到一个标题,就回想一下对应的解题思路,这样很快就可以系统性的复习一遍二叉树了。文章的顺序,实际就是循序渐进的,所以如下分类基本就是按照文章发文顺序来的,我再做一个系统性的分类。
2024-10-01 15:50:57 1119
原创 538. 把二叉搜索树转换为累加树
经历了前面各种二叉树增删改查的洗礼之后,这道题目应该比较简单了。好了,二叉树已经接近尾声了,接下来就是要对二叉树来一个大总结了。
2024-10-01 14:39:58 692
原创 108. 将有序数组转换为二叉搜索树
在二叉树专题中,已经写了多道构造二叉树的题目了,其实思路也是一样的,不断中间分割,然后递归处理左区间,右区间,也可以说是分治。此时相信大家应该对通过递归函数的返回值来增删二叉树很熟悉了,这也是常规操作。在定义区间的过程中我们又一次强调了循环不变量的重要性。
2024-10-01 14:06:16 981
原创 669. 修剪二叉搜索树
修剪二叉搜索树其实并不难,但在递归法中大家可看出我费了很大的功夫来讲解如何删除节点的,这个思路其实是比较绕的。最终的代码倒是很简洁。如果不对递归有深刻的理解,这道题目还是有难度的!
2024-10-01 01:08:04 625
原创 450. 删除二叉搜索树中的节点
读完本篇,大家会发现二叉搜索树删除节点比增加节点复杂的多。因为二叉搜索树添加节点只需要在叶子上添加就可以的,不涉及到结构的调整,而删除节点操作涉及到结构的调整。这里我们依然使用递归函数的返回值来完成把节点从二叉树中移除的操作。这里最关键的逻辑就是第五种情况(删除一个左右孩子都不为空的节点),这种情况一定要想清楚。而且就算想清楚了,对应的代码也未必可以写出来,所以这道题目既考察思维逻辑,也考察代码能力。
2024-09-30 23:22:29 863
原创 701. 二叉搜索树中的插入操作
首先在二叉搜索树中的插入操作,大家不用恐惧其重构搜索树,其实根本不用重构。然后在递归中,我们重点讲了如何通过递归函数的返回值完成新加入节点和其父节点的赋值操作,并强调了搜索树的有序性。
2024-09-30 02:07:02 610
原创 235. 二叉搜索树的最近公共祖先
对于二叉搜索树的最近祖先问题,其实要比普通二叉树公共祖先问题简单的多。不用使用回溯,二叉搜索树自带方向性,可以方便的从上向下查找目标区间,遇到目标区间内的节点,直接返回。最后给出了对应的迭代法,二叉搜索树的迭代法甚至比递归更容易理解,也是因为其有序性(自带方向性),按照目标区间找就行了。
2024-09-30 00:10:36 850
原创 236. 二叉树的最近公共祖先
这道题目刷过的同学未必真正了解这里面回溯的过程,以及结果是如何一层一层传上去的。求最小公共祖先,需要从底向上遍历,那么二叉树,只能通过后序遍历(即:回溯)实现从底向上的遍历方式。在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。但是公共祖先是p或q自身时,其实没有不是每个节点都遍历了,比如下图遍历到4的时候就返回了,4的子树不会遍历了。要理解如果返回值left为空,right不为空为什么要返回。
2024-09-29 23:18:29 926
原创 501. 二叉搜索树中的众数
本题在递归法中,我给出了如果是普通二叉树,应该怎么求众数。知道了普通二叉树的做法时候,我再进一步给出二叉搜索树又应该怎么求众数,这样鲜明的对比,相信会对二叉树又有更深层次的理解了。在递归遍历二叉搜索树的过程中,我还介绍了一个统计最高出现频率元素集合的技巧, 要不然就要遍历两次二叉搜索树才能把这个最高出现频率元素的集合求出来。为什么没有这个技巧一定要遍历两次呢?因为要求的是集合,会有多个众数,如果规定只有一个众数,那么就遍历一次稳稳的了。
2024-09-28 22:31:31 1181
原创 530. 二叉搜索树的最小绝对差
遇到在二叉搜索树上求什么最值,求差值之类的,都要思考一下二叉搜索树可是有序的,要利用好这一特点。同时要学会在递归遍历的过程中如何记录前后两个指针,这也是一个小技巧,学会了还是很受用的。后面我将继续介绍一系列利用二叉搜索树特性的题目。
2024-09-28 20:10:38 258
原创 98. 验证二叉搜索树
这道题目是一个简单题,但对于没接触过的同学还是有难度的。所以初学者刚开始学习算法的时候,看到简单题目没有思路很正常,千万别怀疑自己智商,学习过程都是这样的,大家智商都差不多。只要把基本类型的题目都做过,总结过之后,思路自然就开阔了,加油💪。
2024-09-28 17:58:33 700
原创 700. 二叉搜索树中的搜索
本篇我们介绍了二叉搜索树的遍历方式,因为二叉搜索树的有序性,遍历的时候要比普通二叉树简单很多。但是一些同学很容易忽略二叉搜索树的特性,所以写出遍历的代码就未必真的简单了。所以针对二叉搜索树的题目,一样要利用其特性。文中我依然给出递归和迭代两种方式,可以看出写法都非常简单,就是利用了二叉搜索树有序的特点。
2024-09-28 13:22:31 746
原创 617. 合并二叉树
合并二叉树,也是二叉树操作的经典题目,如果没有接触过的话,其实并不简单,因为我们习惯了操作一个二叉树,一起操作两个二叉树,还会有点懵懵的。迭代法中,一般一起操作两个树都是使用队列模拟类似层序遍历,同时处理两个树的节点,这种方式最好理解,如果用模拟递归的思路的话,要复杂一些。
2024-09-28 12:41:23 893
原创 654. 最大二叉树
注意类似用数组构造二叉树的题目,每次分割尽量不要定义新的数组,而是通过下标索引直接在原数组上操作,这样可以节约时间和空间上的开销。一些同学也会疑惑,什么时候递归函数前面加if,什么时候不加if,这个问题我在最后也给出了解释。如果让空节点(空指针)进入递归,就不加if,如果不让空节点进入递归,就加if限制一下, 终止条件也会相应的调整。
2024-09-28 12:08:17 698
原创 106. 从中序与后序遍历序列构造二叉树
中序数组我们都切成了左中序数组和右中序数组了,那么后序数组就可以按照左中序数组的大小来切割,切成左后序数组和右后序数组。首先后序数组的最后一个元素指定不能要了,这是切割点 也是 当前二叉树中间节点的元素,已经用了。后序数组没有明确的切割元素来进行左右切割,不像中序数组有明确的切割点,切割点左右分开就可以了。切割点在后序数组的最后一个元素,就是用这个元素来切割中序数组的,所以必须要先切割中序数组。第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)而中序数组的右边界则是。
2024-09-28 00:54:02 1166
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人