今日内容:
● 669. 修剪二叉搜索树
● 108.将有序数组转换为二叉搜索树
● 538.把二叉搜索树转换为累加树
● 总结篇
详细布置
669. 修剪二叉搜索树
这道题目比较难,比 添加增加和删除节点难的多,建议先看视频理解。
题目链接/文章讲解: https://programmercarl.com/0669.%E4%BF%AE%E5%89%AA%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91.html
视频讲解: https://www.bilibili.com/video/BV17P41177ud
class Solution { public TreeNode trimBST(TreeNode root, int low, int high) { if (root == null) { return null; } if (root.val < low) { return trimBST(root.right, low, high); } if (root.val > high) { return trimBST(root.left, low, high); } // root在[low,high]范围内 root.left = trimBST(root.left, low, high); root.right = trimBST(root.right, low, high); return root; } }
108.将有序数组转换为二叉搜索树
本题就简单一些,可以尝试先自己做做。
视频讲解:https://www.bilibili.com/video/BV1uR4y1X7qL
class Solution { public TreeNode sortedArrayToBST(int[] nums) { return sortedArrayToBST(nums, 0, nums.length); } public TreeNode sortedArrayToBST(int[] nums, int left, int right) { if (left >= right) { return null; } if (right - left == 1) { return new TreeNode(nums[left]); } int mid = left + (right - left) / 2; TreeNode root = new TreeNode(nums[mid]); root.left = sortedArrayToBST(nums, left, mid); root.right = sortedArrayToBST(nums, mid + 1, right); return root; } }
538.把二叉搜索树转换为累加树
本题也不难,在 求二叉搜索树的最小绝对差 和 众数 那两道题目 都讲过了 双指针法,思路是一样的。
视频讲解:https://www.bilibili.com/video/BV1d44y1f7wP
累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。
class Solution { int sum; public TreeNode convertBST(TreeNode root) { sum = 0; convertBST1(root); return root; } public void convertBST1(TreeNode root) { //右中左遍历 if (root == null) { return; } convertBST1(root.right); sum += root.val; root.val = sum; convertBST1(root.left); } }
总结篇
好了,二叉树大家就这样刷完了,做一个总结吧
https://programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E6%80%BB%E7%BB%93%E7%AF%87.html
递归三部曲来分析题目,相信大家以后看到二叉树,看到递归,都会想:返回值、参数是什么?终止条件是什么?单层逻辑是什么?
二叉树的理论基础
- 关于二叉树,你该了解这些!(opens new window):二叉树的种类、存储方式、遍历方式、定义方式
#二叉树的遍历方式
- 深度优先遍历
- 广度优先遍历
- 二叉树的层序遍历(opens new window):通过队列模拟
#求二叉树的属性
- 递归:后序,比较的是根节点的左子树与右子树是不是相互翻转
- 迭代:使用队列/栈将两个节点顺序放入容器中进行比较
- 递归:后序,求根节点最大高度就是最大深度,通过递归函数的返回值做计算树的高度
- 迭代:层序遍历
- 递归:后序,求根节点最小高度就是最小深度,注意最小深度的定义
- 迭代:层序遍历
- 递归:后序,通过递归函数的返回值计算节点数量
- 迭代:层序遍历
- 递归:后序,注意后序求高度和前序求深度,递归过程判断高度差
- 迭代:效率很低,不推荐
- 递归:前序,方便让父节点指向子节点,涉及回溯处理根节点到叶子的所有路径
- 迭代:一个栈模拟递归,一个栈来存放对应的遍历路径
- 详解二叉树:找所有路径(opens new window)中递归如何隐藏着回溯
- 递归:后序,必须三层约束条件,才能判断是否是左叶子。
- 迭代:直接模拟后序遍历
- 递归:顺序无所谓,优先左孩子搜索,同时找深度最大的叶子节点。
- 迭代:层序遍历找最后一行最左边
- 递归:顺序无所谓,递归函数返回值为bool类型是为了搜索一条边,没有返回值是搜索整棵树。
- 迭代:栈里元素不仅要记录节点指针,还要记录从头结点到该节点的路径数值总和
#二叉树的修改与构造
- 递归:前序,交换左右孩子
- 迭代:直接模拟前序遍历
- 递归:前序,重点在于找分割点,分左右区间构造
- 迭代:比较复杂,意义不大
- 递归:前序,分割点为数组最大值,分左右区间构造
- 迭代:比较复杂,意义不大
- 递归:前序,同时操作两个树的节点,注意合并的规则
- 迭代:使用队列,类似层序遍历
#求二叉搜索树的属性
- 递归:二叉搜索树的递归是有方向的
- 迭代:因为有方向,所以迭代法很简单
- 递归:中序,相当于变成了判断一个序列是不是递增的
- 迭代:模拟中序,逻辑相同
- 递归:中序,双指针操作
- 迭代:模拟中序,逻辑相同
- 递归:中序,清空结果集的技巧,遍历一遍便可求众数集合
- 二叉搜索树转成累加树(opens new window)
- 递归:中序,双指针操作累加
- 迭代:模拟中序,逻辑相同
#二叉树公共祖先问题
- 递归:后序,回溯,找到左子树出现目标值,右子树节点目标值的节点。
- 迭代:不适合模拟回溯
- 递归:顺序无所谓,如果节点的数值在目标区间就是最近公共祖先
- 迭代:按序遍历
#二叉搜索树的修改与构造
- 递归:顺序无所谓,通过递归函数返回值添加节点
- 迭代:按序遍历,需要记录插入父节点,这样才能做插入操作
- 递归:前序,想清楚删除非叶子节点的情况
- 迭代:有序遍历,较复杂
- 递归:前序,通过递归函数返回值删除节点
- 迭代:有序遍历,较复杂
- 递归:前序,数组中间节点分割
- 迭代:较复杂,通过三个队列来模拟
最后总结
在二叉树题目选择什么遍历顺序是不少同学头疼的事情,我们做了这么多二叉树的题目了,Carl给大家大体分分类。
- 涉及到二叉树的构造,无论普通二叉树还是二叉搜索树一定前序,都是先构造中节点。
- 求普通二叉树的属性,一般是后序,一般要通过递归函数的返回值做计算。
- 求二叉搜索树的属性,一定是中序了,要不白瞎了有序性了。
注意在普通二叉树的属性中,我用的是一般为后序,例如单纯求深度就用前序,二叉树:找所有路径(opens new window)也用了前序,这是为了方便让父节点指向子节点。
所以求普通二叉树的属性还是要具体问题具体分析。
标签:递归,随想录,二叉,window,搜索,二叉树,new,opens From: https://www.cnblogs.com/gaoyuan2lty/p/17048324.html