数据结构算法
文章平均质量分 74
夏目友人不还账
这个作者很懒,什么都没留下…
展开
-
实现 Trie (前缀树)
坏处是使用的空间通常是「TrieNode」方式的数倍,而且由于通常对行的估算会很大,导致使用的二维数组开得很大,如果这时候每次创建Trie对象时都去创建数组的话,会比较慢,而且当样例多的时候甚至会触发 GC(因为OJ每测试一个样例会创建一个Trie对象)。Trie 树(又叫「前缀树」或「字典树」)是一种用于快速查询「某个字符串/字符前缀」是否存在的数据结构。其核心是使用「边」来代表有无字符,使用「点」来记录是否为「单词结尾」以及「其后续字符串的字符是什么」。原创 2023-10-05 19:49:12 · 65 阅读 · 0 评论 -
并查集理论基础
在第一次查询的时候,相当于是n叉树上从叶子节点到根节点的查询过程,时间复杂度是logn,但路径压缩后,后面的查询操作都是O(1),而 join 函数 和 isSame函数 里涉及的查询操作也是一样的过程。因为 find 函数向上寻找根节点,father[u] 表述 u 的父节点,那么让 father[u] 直接获取 find函数 返回的根节点,这样就让节点 u 的父节点 变成根节点。我们需要 father[C] = C,即C的根也为C,这样就方便表示 A,B,C 都在同一个集合里了。原创 2023-09-22 09:44:26 · 110 阅读 · 0 评论 -
广度优先搜索理论基础
我们从图中可以看出,从start起点开始,是一圈一圈,向外搜索,方格编号1为第一步遍历的节点,方格编号2为第二步遍历的节点,第四步的时候我们找到终止点end。我们用一个方格地图,假如每次搜索的方向为 上下左右(不包含斜上方),那么给出一个start起始位置,那么BFS就是从四个方向走出第一步。在第五步,第六步 我只把关键的节点染色了,其他方向周边没有去染色,大家只要关注关键地方染色的逻辑就可以。因为广搜是从起点出发,以起始点为中心一圈一圈进行搜索,一旦遇到终点,记录之前走过的节点就是一条最短路。原创 2023-09-20 11:28:50 · 97 阅读 · 0 评论 -
深度优先搜索理论基础
又找到了一条从节点1到节点6的路径,又到黄河了,此时再回头,下图图五,路径6撤销(回溯的过程),改为路径7,路径8 和 路径7,路径9, 结果发现死路一条,都走到了自己走过的节点。那么节点2所连接路径和节点3所链接的路径 都走过了,撤销路径只能向上回退,去选择撤销当初节点4的选择,也就是撤销路径5,改为路径10。又找到了一条从节点1到节点6的路径,又到黄河了,此时再回头,下图图四中,路径4撤销(回溯的过程),改为路径5。此时我们找到了节点6,(遇到黄河了,是不是应该回头了),那么应该再去搜索其他方向了。原创 2023-09-20 10:59:17 · 61 阅读 · 0 评论 -
71 简化路径
存在多个连续斜杠的情况需要去除,且不便于返回上级目录(弹出栈顶元素),故不存储!) 表示将目录切换到上一级(指向父目录);任意多个连续的斜杠(即,当遇到两个点时,需返回上级目录,类似于栈弹出栈顶元素的操作,因此想到使用栈!,表示指向某一文件或目录的 Unix 风格。遇到非斜杠,统计两斜杠间的字符串,再进行判断!开头),请你将其转化为更加简洁的规范路径。对于此问题,任何其他格式的点(例如,在 Unix 风格的文件系统中,一个点(: 用一个栈维护路径中的 文件/目录名。,直接跳过,不做操作。原创 2023-09-13 22:26:03 · 47 阅读 · 0 评论 -
455 分发饼干
if 里的 index 指向 胃口 10, for 里的 i 指向饼干 9,因为 饼干 9 满足不了 胃口 10,所以 i 持续向前移动,而 index 走不到。外面的 for 是里的下标 i 是固定移动的,而 if 里面的下标 index 是符合条件才移动的。的逻辑,所以 index 不会移动,那么当 i 持续向前移动,最后所有的饼干都匹配不上。大尺寸的饼干既可以满足胃口大的孩子也可以满足胃口小的孩子,那么就应该优先满足胃口大的。先遍历的胃口,在遍历的饼干,那么可不可以 先遍历 饼干,在遍历胃口呢?原创 2023-08-21 14:19:52 · 74 阅读 · 0 评论 -
37 解数独
因为解数独找到一个符合的条件(就在树的叶子节点上)立刻就返回,相当于找从根节点到叶子节点一条唯一路径,所以需要使用bool返回值。递归的下一层的棋盘一定比上一层的棋盘多一个数,等数填满了棋盘自然就终止(填满当然好了,说明找到结果了),所以不需要终止条件!N皇后问题是因为每一行每一列只放一个皇后,只需要一层for循环遍历一行,递归来遍历列,然后一行一列确定皇后的唯一位置。因为如果一行一列确定下来了,这里尝试了9个数都不行,说明这个棋盘找不到解决数独问题的解!编写一个程序,通过填充空格来解决数独问题。原创 2023-08-21 13:35:49 · 56 阅读 · 0 评论 -
51 N皇后
递归深度就是row控制棋盘的行,每一层里for循环的col控制棋盘的列,一行一列,确定了放置皇后的位置。因为在单层搜索的过程中,每一层递归,只会选for循环(也就是同一行)里的一个元素,所以不用去重了。从图中,可以看出,二维矩阵中矩阵的高就是这棵树的高度,矩阵的宽就是树形结构中每一个节点的宽度。确定完约束条件,来看看究竟要怎么去搜索皇后们的位置,其实搜索皇后的位置,可以抽象为一棵树。可以看出,除了验证棋盘合法性的代码,省下来部分就是按照回溯法模板来的。那么用皇后们的约束条件,来回溯搜索这棵树,原创 2023-08-21 11:28:22 · 70 阅读 · 0 评论 -
40 组合总和II
可能有的录友想,为什么 used[i - 1] == false 就是同一树层呢,因为同一树层,used[i - 1] == false 才能表示,当前取的 candidates[i] 是从 candidates[i - 1] 回溯而来的。都知道组合问题可以抽象为树形结构,那么“使用过”在这个树形结构上是有两个维度的,一个维度是同一树枝上使用过,一个维度是同一树层上使用过。要去重的是“同一树层上的使用过”,如何判断同一树层上元素(相同的元素)是否使用过了呢。**注意:**解集不能包含重复的组合。原创 2023-07-17 16:30:51 · 57 阅读 · 0 评论 -
47 全排列 II
树层上对前一位去重非常彻底,效率很高,树枝上对前一位去重虽然最后可以得到答案,但是做了很多无用搜索。对同一树层,前一位(也就是nums[i-1])如果使用过,那么就进行去重。给定一个可包含重复数字的序列。这道题目和46全排列的区别在与。如果要对树层中前一位去重,就用。[1,1,1] 来举一个例子。返回所有不重复的全排列。,如果要对树枝前一位去重用。去重最为关键的代码为。原创 2023-07-07 14:01:37 · 68 阅读 · 0 评论 -
46 全排列
可以看出元素1在[1,2]中已经使用过了,但是在[2,1]中还要在使用一次1,所以处理排列问题就不用使用startIndex了。因为排列问题,每次都要从头开始搜索,例如元素1在[1,2]中已经使用过了,但是在[2,1]中还要再使用一次1。当收集元素的数组path的大小达到和nums数组一样大的时候,说明找到了一个全排列,也表示到达了叶子节点。可以看出叶子节点,就是收割结果的地方。那么什么时候,算是到达叶子节点呢?给定一个不含重复数字的数组。原创 2023-07-07 11:16:40 · 59 阅读 · 0 评论 -
491 递增子序列
给你一个整数数组 ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。示例 1:示例 2:思路这个递增子序列比较像是取有序的子集。而且本题也要求不能有相同的递增子序列。而本题求自增子序列,是不能对原数组进行排序的,排完序的数组都是自增子序列了。所以不能使用之前的去重逻辑!本题给出的示例,还是一个有序数组 [4, 6, 7, 7],这更容易误导大家按照排序的思路去做了。为了原创 2023-07-07 10:21:06 · 56 阅读 · 0 评论 -
90 子集II
从图中可以看出,同一树层上重复取2 就要过滤掉,同一树枝上就可以重复取2,因为同一树枝上元素的集合才是唯一子集!这道题目和78 子集区别就是集合里有重复元素了,而且求取的子集要去重。,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。用示例中的[1, 2, 2] 来举例,如图所示: (返回的解集中,子集可以按。使用set去重的版本。原创 2023-07-07 09:31:54 · 47 阅读 · 0 评论 -
78 子集
全局变量数组path为子集收集元素,二维数组result存放子集组合。其实子集也是一种组合问题,因为它的集合是无序的,子集{1,2} 和 子集{2,1}是一样的。求排列问题的时候,就要从0开始,因为集合是有序的,{1, 2} 和{2, 1}是两个集合。如果把 子集问题、组合问题、分割问题都抽象为一棵树的话,递归函数参数在上面讲到了,需要startIndex。但是要清楚子集问题和组合问题、分割问题的的区别,返回该数组所有可能的子集(幂集)。剩余集合为空的时候,就是叶子节点。从图中红线部分,可以看出。原创 2023-07-06 16:08:14 · 88 阅读 · 0 评论 -
93 复原IP地址
题明确要求只会分成4段,所以不能用切割线切到最后作为终止条件,而是分割的段数作为终止条件。循环中 [startIndex, i] 这个区间就是截取的子串,需要判断这个子串是否合法。递归调用时,下一层递归的startIndex要从i+2开始(因为需要在字符串中加入了分隔符。startIndex一定是需要的,因为不能重复分割,记录下一层递归分割的起始位置。pointNum表示逗点数量,pointNum为3说明字符串分成了4段了。,和刚做过的131分割回文串就十分类似了。回溯的时候,就将刚刚加入的分隔符。原创 2023-07-05 16:13:09 · 67 阅读 · 0 评论 -
131 分割回文串
在处理组合问题的时候,递归参数需要传入startIndex,表示下一轮递归遍历的起始位置,这个startIndex就是切割线。原创 2023-07-05 15:28:03 · 58 阅读 · 0 评论 -
40 组合总和II
为什么 used[i - 1] == false 就是同一树层呢,因为同一树层,used[i - 1] == false 才能表示,当前取的 candidates[i] 是从 candidates[i - 1] 回溯而来的。都知道组合问题可以抽象为树形结构,那么“使用过”在这个树形结构上是有两个维度的,一个维度是同一树枝上使用过,一个维度是同一树层上使用过。要去重的是“同一树层上的使用过”,如何判断同一树层上元素(相同的元素)是否使用过了呢。这个集合去重的重任就是used来完成的。原创 2023-07-05 14:52:36 · 44 阅读 · 0 评论 -
39 组合总和
此外我还定义了int型的sum变量来统计单一结果path里的总和,其实这个sum也可以不用,用target做相应的减法就可以了,最后如何target==0就说明找到符合的结果了,但为了代码逻辑清晰,我依然用了sum。注意图中叶子节点的返回条件,因为本题没有组合数量要求,仅仅是总和的限制,所以递归没有层数的限制,只要选取的元素总和超过target,就返回!于sum已经大于target的情况,其实是依然进入了下一层递归,只是下一层递归结束判断的时候,会判断sum > target的话就返回。原创 2023-07-02 16:47:27 · 43 阅读 · 0 评论 -
17 电话号码的字母组合
图中可以看出遍历的深度,就是输入"23"的长度,而叶子节点就是我们要收集的结果,输出[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”]。一些写法,是把回溯的过程放在递归函数里了,例如如下代码,我可以写成这样:(注意注释中不一样的地方)从示例上来说,输入"23",最直接的想法就是两层for循环遍历了吧,正好把组合的情况都输出了。例如输入用例"23",两个数字,那么根节点往下递归两层就可以了,叶子节点就是要收集的结果集。然后收集结果,结束本层递归。原创 2023-07-02 15:57:08 · 74 阅读 · 0 评论 -
216 组合总和III
其实这里sum这个参数也可以省略,每次targetSum减去选取的元素数值,然后判断如果targetSum为0了,说明收集到符合条件的结果了,我这里为了直观便于理解,还是加一个sum参数。例如 k = 2,n = 4的话,就是在集合[1,2,3,4,5,6,7,8,9]中求 k(个数) = 2, n(和) = 4的组合。本题就是在[1,2,3,4,5,6,7,8,9]这个集合中找到和为n的k个数的组合。在上面已经说了,k其实就已经限制树的深度,因为就取k个元素,树再往下深了没有意义。原创 2023-07-02 15:24:23 · 74 阅读 · 0 评论 -
77 组合
从下图中红线部分可以看出,在集合[1,2,3,4]取1之后,下一层递归,就要在[2,3,4]中取数了,那么下一层递归如何知道从[2,3,4]中取数呢,靠的就是startIndex。第一次取1,集合变为2,3,4 ,因为k为2,我们只需要再取一个数就可以了,分别取2,3,4,得到集合[1,2] [1,3] [1,4],以此类推。可以看出这棵树,一开始集合是 1,2,3,4, 从左向右取数,取过的数,不再重复取。此时递归的层数大家应该知道了,例如:n为100,k为50的情况下,就是递归50层。原创 2023-06-28 16:47:56 · 51 阅读 · 0 评论 -
回溯法理论基础
例如:{1, 2} 和 {2, 1} 在组合上,就是一个集合,因为不强调顺序,而要是排列的话,{1, 2} 和 {2, 1} 就是两个集合了。再来看一下参数,因为回溯算法需要的参数可不像二叉树递归的时候那么容易一次性确定下来,所以一般是先写逻辑,然后需要什么参数,就填什么参数。什么时候达到了终止条件,树中就可以看出,一般来说搜到叶子节点了,也就找到了满足条件的一条答案,把这个答案存放起来,并结束本层递归。回溯法一般是在集合中递归搜索,集合的大小构成了树的宽度,递归的深度构成的树的深度。原创 2023-06-06 17:19:47 · 129 阅读 · 1 评论 -
538 把二叉搜索树转换为累加树
给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。因为数组都知道怎么遍历啊,从后向前,挨个累加就完事了,这换成了二叉搜索树,看起来就别扭了一些是不是。同时需要定义一个全局变量pre,用来保存cur节点的前一个节点的数值,定义为int型就可以了。, 中节点的处理逻辑就是让cur的数值加上前一个节点的数值。节点的右子树仅包含键 大于 节点键的节点。左右子树也必须是二叉搜索树。原创 2023-06-05 21:56:01 · 47 阅读 · 0 评论 -
108 将有序数组转换为二叉搜索树
给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。示例 1:示例 2:思路题目中说要转换为一棵高度平衡二叉搜索树。为什么强调要平衡呢?因为只要给我们一个有序数组,如果强调平衡,都可以以线性结构来构造二叉搜索树。例如 有序数组[-10,-3,0,5,9] 就可以构造成这样的二叉搜索树,如图。上图中,是符合二叉搜索树的特性吧,如果要这么做的话,是不是本题意义就不大了,原创 2023-06-05 21:35:54 · 125 阅读 · 0 评论 -
669 修剪二叉搜索树
修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。因为是要遍历整棵树,做修改,其实不需要返回值也可以,我们也可以完成修剪(其实就是从二叉树中移除节点)的操作。如果root(当前节点)的元素小于low的数值,那么应该递归右子树,并返回右子树符合条件的头结点。如果root(当前节点)的元素大于high的,那么应该递归左子树,并返回左子树符合条件的头结点。然后如下代码相当于用节点3的左孩子 把下一层返回的 节点0的右孩子(节点2) 接住。原创 2023-06-02 21:32:01 · 63 阅读 · 0 评论 -
450 删除二叉搜索树中的节点
给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。通用的删除,普通二叉树的删除方式(没有使用搜索树的特性,遍历整棵树),用交换值的操作来删除目标节点。遇到空返回,其实这也说明没找到删除的节点,遍历到空节点直接返回了。这里就把二叉搜索树中删除节点遇到的情况都搞清楚。代码如下:(关键部分已经注释)首先找到需要删除的节点;如果找到了,删除它。原创 2023-06-02 20:57:03 · 50 阅读 · 0 评论 -
701 二叉搜索树中的插入操作
给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。没有返回值,需要记录上一个节点(parent),遇到空节点了,就让parent左孩子或者右孩子指向新插入的节点。刚刚说了递归函数不用返回值也可以,找到插入的节点位置,直接让其父节点指向插入节点,结束递归,也是可以的。例如插入元素10 ,需要找到末尾节点插入便可,一样的道理来插入元素15,插入元素0,插入元素6,终止条件就是找到遍历的节点为null的时候,就是要插入节点的位置了,并把插入的节点返回。原创 2023-05-26 15:09:13 · 72 阅读 · 0 评论 -
235 二叉搜索树的最近公共祖先
剩下的情况,就是cur节点在区间(p->val <= cur->val && cur->val <= q->val)或者 (q->val <= cur->val && cur->val <= p->val)中,那么cur就是最近公共祖先了,直接返回cur。如图,我们从根节点搜索,第一次遇到 cur节点是数值在[p, q]区间中,即 节点5,此时可以说明 p 和 q 一定分别存在于 节点 5的左子树,和右子树中。利用回溯从底向上搜索,遇到一个节点的左子树里有p,右子树里有q,那么当前节点就是最近公共祖先。原创 2023-05-25 22:52:41 · 51 阅读 · 0 评论 -
236 二叉树的最近公共祖先
那么我们来说一说,如果 root == q,或者 root == p,说明找到 q p ,则将其返回,这个返回值,后面在中节点的处理过程中会用到,那么中节点的处理逻辑,下面讲解。但我们还要返回最近公共节点,可以利用上题目中返回值是TreeNode * ,那么如果遇到p或者q,就把q或者p返回,返回值不为空,就说明找到了q或者p。判断逻辑是 如果递归遍历遇到q,就将q返回,遇到p 就将p返回,那么如果 左右子树的返回值都不为空,说明此时的中节点,一定是q 和p 的最近祖先。原创 2023-05-25 16:25:58 · 66 阅读 · 0 评论 -
501 二叉搜索树中的众数
频率count 大于 maxCount的时候,不仅要更新maxCount,而且要清空结果集(以下代码为result数组),因为结果集之前的元素都失效了。给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。如果不是二叉搜索树,最直观的方法一定是把这个树都遍历了,用map统计频率,把频率排个序,最后取前面高频的元素的集合。遍历有序数组的元素出现频率,从头遍历,那么一定是相邻两个元素作比较,然后就把出现频率最高的元素输出就可以了。原创 2023-05-25 15:52:16 · 64 阅读 · 0 评论 -
530 二叉搜索树的最小绝对差
遇到在二叉搜索树上求什么最值啊,差值之类的,就把它想成在一个有序数组上求最值,求差值,这样就简单多了。以上代码是把二叉搜索树转化为有序数组了,其实在二叉搜素树中序遍历的过程中,我们就可以直接计算了。最直观的想法,就是把二叉搜索树转换成有序数组,然后遍历一遍数组,就统计出来最小差值了。题目中要求在二叉搜索树上任意两节点的差的绝对值的最小值。需要用一个pre节点记录一下cur节点的前一个节点。那么二叉搜索树采用中序遍历,其实就是一个有序数组。差值是一个正数,其数值等于两值之差的绝对值。,二叉搜索树可是有序的。原创 2023-05-25 15:17:28 · 77 阅读 · 0 评论 -
98 验证二叉搜索树
要定义一个longlong的全局变量,用来比较遍历的节点是否有序,因为后台测试数据中有int最小值,所以定义为longlong的类型,初始化为longlong最小值。以上代码中,我们把二叉树转变为数组来判断,是最直观的,但其实不用转变成数组,可以在递归遍历的过程中直接判断是否有序。在寻找一个不符合条件的节点,如果没有找到这个节点就遍历了整个树,如果找到不符合的节点了,立刻返回。样例中最小节点 可能是int的最小值,如果这样使用最小的int来比较也是不行的。节点的左子树只包含 小于 当前节点的数。原创 2023-05-25 14:50:06 · 45 阅读 · 0 评论 -
700 二叉搜索树中的搜索
如果root->val > val,搜索左子树,如果root->val < val,就搜索右子树,最后如果都没有搜索到,就返回NULL。对于二叉搜索树可就不一样了,因为二叉搜索树的特殊性,也就是节点的有序性,可以不使用辅助栈或者队列就可以写出迭代法。对于一般二叉树,递归过程中还有回溯的过程,例如走一个左方向的分支走到头了,那么要调头,在走右分支。递归函数的参数传入的就是根节点和要搜索的数值,返回的就是以这个搜索数值所在的节点。因为二叉搜索树的节点是有序的,所以可以有方向的去搜索。例如要搜索元素为3的节点,原创 2023-05-25 14:28:27 · 42 阅读 · 0 评论 -
617 合并二叉树
因为是传入了两个树,那么就有两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就应该是 t2 了(如果t2也为NULL也无所谓,合并之后就是NULL)。单层递归的逻辑就比较好写了,这里我们重复利用一下t1这个树,t1就是合并之后树的根节点(就是修改了原来树的结构)。反过来如果t2 == NULL,那么两个数合并就是t1(如果t1也为NULL也无所谓,合并之后就是NULL)。首先要合入两个二叉树,那么参数至少是要传入两个二叉树的根节点,返回值就是合并之后二叉树的根节点。原创 2023-05-25 11:35:08 · 44 阅读 · 0 评论 -
654 最大二叉树
题目中说了输入的数组大小一定是大于等于1的,所以我们不用考虑小于1的情况,那么当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。那么应该定义一个新的节点,并把这个数组的数值赋给新的节点,然后返回这个节点。这表示一个数组大小是1的时候,构造了一个新的节点,并返回。以上代码比较冗余,效率也不高,每次还要切割的时候每次都要定义新的vector(也就是数组),但逻辑比较清晰。参数传入的是存放元素的数组,返回该数组构造的二叉树的头结点,返回类型是指向节点的指针。返回 nums 构建的 最大二叉树。原创 2023-05-24 22:44:05 · 72 阅读 · 0 评论 -
106 从中序与后序遍历序列构造二叉树
首先回忆一下如何根据两个顺序构造一个唯一的二叉树,就是以 后序数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来再切后序数组。中序数组我们都切成了左中序数组和右中序数组了,那么后序数组就可以按照左中序数组的大小来切割,切成左后序数组和右后序数组。切割点在后序数组的最后一个元素,就是用这个元素来切割中序数组的,所以必要先切割中序数组。此时,中序数组切成了左中序数组和右中序数组,后序数组切割成左后序数组和右后序数组。首先要切割中序数组,为什么先切割中序数组呢?接下来就要切割后序数组了。原创 2023-05-22 21:15:19 · 103 阅读 · 0 评论 -
112 路径总和
不要去累加然后判断是否等于目标和,那么代码比较麻烦,可以用递减,让计数器count初始为目标和,然后每次减去遍历路径节点上的数值。参数:需要二叉树的根节点,还需要一个计数器,这个计数器用来计算二叉树的一条边之和是否正好是目标和,计数器为int型。图中可以看出,遍历的路线,并不要遍历整棵树,所以递归函数需要返回值,可以用bool类型表示。而本题要找一条符合条件的路径,所以递归函数需要返回值,及时返回,那么返回类型是什么呢?递归函数是有返回值的,如果递归函数返回true,说明找到了合适的路径,应该立刻返回。原创 2023-05-20 22:17:57 · 59 阅读 · 0 评论 -
513 找树左下角的值
找到。原创 2023-05-20 20:54:28 · 60 阅读 · 0 评论 -
404 左叶子之和
注意,只有当前遍历的节点是父节点,才能判断其子节点是不是左叶子。当遇到左叶子节点的时候,记录数值,然后通过递归求取左子树左叶子之和,和 右子树左叶子之和,相加便是整个树的左叶子之和。判断一个树的左叶子节点之和,那么一定要传入树的根节点,递归函数的返回值为数值之和,所以为int。递归的遍历顺序为后序遍历(左右中),是因为要通过递归函数的返回值来累加求取左叶子数值之和。本题迭代法使用前中后序都是可以的,只要把左叶子节点统计出来,就可以了。如果遍历到空节点,那么左叶子值一定是0。但看这个图的左叶子之和是多少?原创 2023-05-20 10:39:07 · 52 阅读 · 0 评论 -
257 二叉树的所有路径
这个回溯就有很大的问题,回溯和递归是一一对应的,有一个递归,就要有一个回溯**,这么写的话相当于把递归和回溯拆开了, 一个在花括号里,一个在花括号外。然后是递归和回溯的过程,上面说过没有判断cur是否为空,那么在这里递归的时候,如果为空就不进行下一层递归了。这道题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。此时还没完,递归完,要做回溯啊,因为path 不能一直加入节点,它还要删节点,然后才能加入新的节点。此时就没有回溯了,这个代码就是通过不了的了。原创 2023-05-20 10:22:36 · 71 阅读 · 0 评论