二叉树
c葱c
这个作者很懒,什么都没留下…
展开
-
二叉树总结
感觉二叉树没啥好总结的。因为学得还不透,所以总会有朦朦胧胧的感觉。觉得递归很奇妙,其实递归很暴力hh。多回顾吧,可能多做几次,就能发现以前没注意到的细节。我觉得做递归题目的时候,只需要把单层需要做的事情想清楚。然后其他的留给递归。结点数、高度(最大深度)、需要用到两个子树传到根结点来判断的,一般都需要用到后序遍历。有道题,求最左下角的值,就需要判断是否到达了最深深度。我觉得很重要的就是终止条件 和 单层逻辑。参数、返回值、终止条件、单层逻辑、因为这样遍历的二叉树是有序的。前、中、后、层次遍历。原创 2023-04-09 16:18:25 · 30 阅读 · 0 评论 -
leetcode 538.把二叉搜索树转换为累加树
双指针不一定是要有结点。有一个可以记录下之前一个的数值即可。在这里因为计算的是值,所以直接将 pre 定义为 int 类型就可以完成了。所以就用到 双指针的想法了。逐个遍历,并且加上之前遍历的总和。因为之前遍历的结点的值,一定比当前结点的值要大。累加树就是 当前结点 加上所有比它大的数值。不知道这个累加树是什么意思。原创 2023-04-06 09:59:50 · 66 阅读 · 0 评论 -
leetcode 108.将有序数组转换为二叉搜索树
这里写的时候犯了个错,就是还用if来判断了一下。其实根本不用,直接根据 数组的中间元素来拆分就可以了。可以用下标来提高效率,不用每次都创建一个新的数组。原创 2023-04-06 09:37:13 · 30 阅读 · 0 评论 -
leetcode 669. 修剪二叉搜索树
2. 小于 low ,根据二叉树的特性,此时root的右子树,还是会可能存在符合条件的结点。(右子树比根结点的值要大。) 所以向此时的 root->right 去遍历,并将符合的结点返回。3. 大于 high。同理,根据二叉树的特性,此时的root的左子树,还是会可能存在符合条件的结点。所以向 root->left去遍历。先判断中间结点是否符合条件。如果符合就继续原样搜索。如果不符合,有三种情况。1. 为空 ,直接返回空。原创 2023-04-06 09:02:30 · 61 阅读 · 0 评论 -
leetcode 450.删除二叉搜索树中的节点
nullptr , 就会导致可能会操作空指针的情况.因为无法保证 cur->left 是否为空。之后要操作的是 cur->left。新意:一开始以为要记录下前一个结点,这样才好记录下一个结点。是 cur->left!如果没找到需要被删除的元素,return nullptr。也就是跳过需要被删除的结点,直接返回下一个结点。所以,当需要操作哪个的时候,就需要保证其不为空。需要分情况讨论,如果找到了 需要被删除的元素。2. 注意在删除左右非空结点的情况下的,1.释放结点的时候,将需要。原创 2023-04-05 11:08:57 · 26 阅读 · 0 评论 -
leetcode 701.二叉搜索树中的插入操作
根据二叉搜索树的特性来的。直接拿 val 和根结点的值作比较。如果大,查看左边是否能插入,不能继续往下递归找。因为接住的就是上一层返回来的新创建的结点。然后再将根结点返回。首先不管三七二十一!注意这里在递归调用函数的时候,虽然有点繁琐~~~~~原创 2023-04-05 09:40:24 · 33 阅读 · 0 评论 -
leetcode 235. 二叉搜索树的最近公共祖先
这里的代码没有进行是否为空的判断,因为题目已经给明表示一定会有q , p在树中,所以不可能为空。本题最重要的就是理解二叉树的性质。原创 2023-04-05 09:14:56 · 30 阅读 · 0 评论 -
leetcode 236. 二叉树的最近公共祖先
1.需要用后序遍历,因为需要根据 左子树 和 右子树,来处理中间逻辑。一个根结点,左右都有。说明root就是需要的结点。说明结果是从左边传上来的。说明结果是从右边传上来的。通过回溯,将结果一层层向上返回。这里 p,q是不同的。原创 2023-04-04 17:02:17 · 63 阅读 · 0 评论 -
leetcode 530.二叉搜索树的最小绝对差
这里使用递归函数是主要是为了遍历,而不需要得到返回值。res已经在每次迭代中不断更新了。关于使用递归是否需要接住返回值。不断比较差值,并且更新res。夸夸 自己写对了一大半。原创 2023-04-04 10:12:52 · 44 阅读 · 0 评论 -
leetcode 501.二叉搜索树中的众数
day21值得一夸的是,思路想出一大半了思路:就是用双指针,不断比较 pre 和 当前结点的值是否相等。原创 2023-04-04 09:56:13 · 37 阅读 · 0 评论 -
leetcode 98.验证二叉搜索树
所以看见二叉搜索树首先可以考虑中序遍历,这样遍历的元素值是逐渐递增的。如果 pre->val >= root->val 返回 false。在这里,使用一个结点,保存之前的结点,可以和现在的结点进行比较。首先,根据二叉搜索树的性质,左子树的。都比 根结点的值小 右子树的。原创 2023-04-03 19:45:28 · 37 阅读 · 0 评论 -
leetcode 700.二叉搜索树中的搜索
val 大于 root->val --------------------> right。比较当前节点,如果是,就返回。如果不是就比较大小。根据大小往不同的方向递归。不断比较 根结点的值 和 val 的大小。1. 要用while , 因为根结点需要不断移动比较。原创 2023-04-03 17:55:14 · 21 阅读 · 0 评论 -
leetcode 617.合并二叉树
2. 这里是直接将 root1 进行改造。(我当时想,既然是改造,那 root2为空的时候,没必要返回root1。因为 root2 为空,但不进行处理的话,后续会操作空指针。1. root1 为 空,就返回 root2 的值。因为 两个二叉树是同步遍历的。与 对称二叉树类似,也是要操作两个二叉树,传入的参数是两个子根结点。2.root2 为空,就返回 root1 的值。碰到叶子节点要怎么办呢?1.终止条件比较难想。原创 2023-04-03 17:42:27 · 53 阅读 · 0 评论 -
leetcode 654.最大二叉树
找到数组中最大值的下标。根据这个下标切割数组,作为参数传递给下一层递归。先构造中间节点,如何递归构造左子树和右子树。1.使用前序遍历构造二叉树。2.使用下标来节省开销。原创 2023-04-03 17:15:23 · 21 阅读 · 0 评论 -
leetcode 106.从中序与后序遍历序列构造二叉树
1. 之前一直以为左闭右开区间,处理不到最后一个结点,所以觉得不删除根结点也没关系。但是这是错的,end 指向的是最后一个元素的下一个位置。所以能处理到最后一个节点(根结点)。所以要将最后一个结点删除。后序划分的时候,因为左右子树的结点都在一块,而根结点在后面。所以就直接处理就行了。所以也就没有 + 1。中序划分的时候,是没有处理那个根结点的。2.在找到根结点之后,不要忘记创建根结点。原创 2023-04-01 15:44:48 · 101 阅读 · 0 评论 -
leetcode 113. 路径总和ii
2. 在最后叶子结点的时候,如果符合条件,就不用再插入叶子结点到path里面了。因为在调用之前就已经插入到path中了。3. 在主函数中,要先将root->val 的值插入path中,因为已经遍历了这个结点。1. vector 都要定义在外面,不然每次递归都会创建新的vector。只不过path里面的元素需要手动 push pop。原创 2023-04-01 10:57:19 · 38 阅读 · 0 评论 -
leetcode 112. 路径总和
在递归的时候,如果返回值是 true 直接 return true。先向左遍历,把下一个点和减去这个点之后的值传入。再向右遍历,把下一个点和减去这个点之后的值传入。count 减去当前遍历的结点后,所剩下的值。用累减的方式来查看是否找到了符合条件的路径。traversal 函数参数的意思。cur 当前遍历的结点。原创 2023-04-01 10:19:57 · 37 阅读 · 0 评论 -
leetcode 513 找树左下角的值(迭代 + 递归)
返回值 0 ,终止条件 : 遍历到叶子结点 单层逻辑 : 每次都只需要处理 左 右 没有中。一开始一直没想到怎样判断是否到了最后一层,没想到可以直接每一个层都记录一下最左边的。,所以等到遍历到最后一次时,就是最左边的第一个!原创 2023-04-01 08:49:04 · 30 阅读 · 0 评论 -
leetcode 404.左叶子之和
2.symbol 默认为 false。因为刚传入根节点的时候,有可能其左右结点都会空。要确保这种i情况下,不会讲 数值 加进去。1. 这里判断是否为左叶子需要在 遍历到其父结点的时候进行标记。用一个标志位记录是 左节点还是 右节点。原创 2023-03-31 15:33:15 · 31 阅读 · 0 评论 -
leetcode 257. 二叉树的所有路径(递归 + 回溯)
所以当函数返回到上一层的时候,用的就是上一层之前的path。遍历到最后一个叶子结点的时候,也就是递归结束的时候。这里就有回溯,因为这里的 " -> " 是直接在函数中的,所以如果返回到上一层的话,就直接会被清空。返回到上一层的时候,需要思考,有没有因为本层的递归而给上一层带来了变化,影响了上一层的结果。这样的话,每次返回到本层的时候,如果从左边到右边的时候, 会发现前面多加了 " -> "。3. 为了代码精简,可以将 "->" 放在函数的参数中,这样就不用手动的pop元素。这里的res 用的是引用传递。原创 2023-03-31 12:06:58 · 40 阅读 · 0 评论 -
leetcode 110.平衡二叉树
写递归的时候,不要陷入到整个是怎样的。要去向一层是怎样完成的,不然很容易晕。想好一层之后,每一层都是一样的。写递归函数的时候,先去思考终止条件。而是先向每一层的递归逻辑。左右孩子应该将结果返还给根节点。同时,这里求的是高度,所以。原创 2023-03-31 10:52:12 · 23 阅读 · 0 评论 -
leetcode 222.完全二叉树的节点个数(递归)
如果深度不一样,就向下一层去遍历,最终最坏的情况就是到最后一个结点,一定是满完全二叉树,就向上返回。2. 2 << leftdepth 相当于是 2 的 leftdepth + 1 次方。,一个是root == nullptr 另一个是一直向左遍历 与 一直向右遍历的深部一样。,原因就是因为这里对 leftdpth + 1 了。就相当于是从 1 开始计算深度。从根节点一直向左或者一直向右去遍历,得到的深度是一样的。降低了时间复杂度,此时不用去遍历所有的结点。后序遍历二叉树(没有利用到二叉树的特性。原创 2023-03-30 09:57:33 · 38 阅读 · 0 评论 -
leetcode 559.n叉树的最大深度
我这里没有想到数组的处理,傻了一下。思路:跟上一题类似。原创 2023-03-30 08:54:22 · 33 阅读 · 0 评论 -
leetcode 104.二叉树的最大深度(递归)
因为要先知道叶子结点有多深,最后再返回给根节点。高度:任意结点到叶子结点的距离。深度:任意结点到根节点的距离。原创 2023-03-30 08:43:00 · 40 阅读 · 0 评论 -
leetcode 101. 对称二叉树(递归)
将是否对称分为 外部是否对称,和 内部是否对称。因为要先知道左右子树是否对称,再返还给根节点。外部:左子树的左孩子 和 右子树的右孩子。内部:左子树的右孩子 和 右子树的左孩子。重要的是:确定遍历的顺序。原创 2023-03-29 10:58:17 · 78 阅读 · 0 评论 -
226.翻转二叉树(递归)
中序有点绕,不建议使用:(主要是交换结点以后,之前处理过的左子树跑到右边,如果继续处理右子树就重复处理了)原创 2023-03-29 10:30:01 · 55 阅读 · 0 评论 -
107.二叉树的层序遍历
不用担心弹出的时候会多弹出,因为设置了size。所以只会按照size的大小弹出。1. vector<int> vec 的位置,要放在大while中。2.加入元素到数组中的时候,别忘记弹出队列中的。因为层序遍历时先进先出的。每次现在队列中记录好一层的大小。2.别忘记将root先加入。原创 2023-03-29 09:11:25 · 32 阅读 · 0 评论 -
迭代法中序遍历二叉树
之前遍历到哪个结点,就可以处理哪个结点。这里是遍历到了暂时不处理,之后再处理。先处理最左边的,再中间,再右边。原创 2023-03-28 19:17:23 · 43 阅读 · 0 评论 -
迭代前后遍历二叉树
所以一开始就处理中间的,将它加入数组中。在前序遍历中,如果左右颠倒,再将数组反转。弹出之后才是中左右的顺序。原创 2023-03-28 16:44:33 · 21 阅读 · 0 评论 -
递归遍历二叉树
出口:当 cur 为空,表示遍历到头了,返回上一层。如果是前序遍历,中左右 把当前的放在最前面。返回值:void,参数,根节点和数组。1. 确认递归函数的返回值和参数。2.确认递归的退出条件(出口。中序遍历 把当前的放在中间。后序遍历 把当前的放在后面。在遍历二叉树中就是,原创 2023-03-28 15:56:26 · 76 阅读 · 0 评论