0


5道真题训练|学会了二叉树的前世今生(二)

很多朋友都问我学完基础知识以后怎样提高编程水平?当然是

刷题

啦!很多小伙伴都在纠结从哪里开始,今天给大家推荐一个身边朋友都在使用的刷题网站:**点击进入牛客网刷题吧! **

在这里插入图片描述

今天是Java进阶刷题的第三天,结合经典算法学习Java语法!一起升级打怪吧!!

文章目录

问题1: 对称的二叉树

👉原题:对称二叉树

在这里插入图片描述

描述

给定一棵二叉树,判断其是否是自身的镜像(即:是否对称)

例如: 下面这棵二叉树是对称的:
在这里插入图片描述

下面这棵二叉树不对称:

在这里插入图片描述

数据范围:节点数满足 0≤n≤1000,节点上的值满足 ∣val∣≤1000

要求:空间复杂度 O(n),时间复杂度 O(n)

备注:你可以用递归和迭代两种方法解决这个问题

示例

示例1

输入:{1,2,2,3,4,4,3}
返回值:true

示例2

输入:{8,6,9,5,7,7,5}
返回值:false

题解

Java代码实现:

publicclassSolution{booleanrecursion(TreeNode root1,TreeNode root2){//可以两个都为空if(root1 ==null&& root2 ==null)returntrue;//只有一个为空或者节点值不同,必定不对称if(root1 ==null|| root2 ==null|| root1.val != root2.val)returnfalse;//每层对应的节点进入递归比较returnrecursion(root1.left, root2.right)&&recursion(root1.right, root2.left);}booleanisSymmetrical(TreeNode pRoot){returnrecursion(pRoot, pRoot);}}

思路:前序遍历的时候我们采用的是“根左右”的遍历次序,如果这棵二叉树是对称的,即相应的左右节点交换位置完全没有问题,那我们是不是可以尝试“根右左”遍历,按照轴对称图像的性质,这两种次序的遍历结果应该是一样的。

不同的方式遍历两次,将结果拿出来比较看起来是一种可行的方法,但也仅仅可行,太过于麻烦。我们不如在遍历的过程就结果比较了。而遍历方式依据前序递归可以使用递归。


问题2:合并二叉树

👉原题:合并二叉树

在这里插入图片描述

描述

已知两颗二叉树,将它们合并成一颗二叉树。合并规则是:都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替。例如,两颗二叉树是:

Tree1:
在这里插入图片描述
Tree2:
在这里插入图片描述
合并后的树为:
在这里插入图片描述

数据范围:树上节点数量满足 0≤n≤500,树上节点的值一定在32位整型范围内。

进阶:空间复杂度 O(1) ,时间复杂度 O(n)

示例

示例1

输入:{1,3,2,5},{2,1,3,#,4,#,7}
返回值:{3,4,5,5,4,#,7}

说明:如题面图

示例2

输入:{1},{}
返回值:{1}

题解

Java代码实现:

importjava.util.*;publicclassSolution{publicTreeNode mergeTrees (TreeNode t1,TreeNode t2){//若只有一个节点返回另一个,两个都为null自然返回nullif(t1 ==null)return t2;if(t2 ==null)return t1;//根左右的方式递归TreeNode head =newTreeNode(t1.val + t2.val);
        head.left =mergeTrees(t1.left, t2.left);
        head.right =mergeTrees(t1.right, t2.right);return head;}}

思路: 要将一棵二叉树的节点与另一棵二叉树相加合并,肯定需要遍历两棵二叉树,那我们可以考虑同步遍历两棵二叉树,这样就可以将每次遍历到的值相加在一起。遍历的方式有多种,这里推荐前序递归遍历。


问题3:二叉树的镜像

👉原题:二叉树的镜像

在这里插入图片描述

描述

操作给定的二叉树,将其变换为源二叉树的镜像。

数据范围:二叉树的节点数 0≤n≤1000 , 二叉树每个节点的值 0≤val≤1000

要求: 空间复杂度 O(n) 。本题也有原地操作,即空间复杂度 O(1) 的解法,时间复杂度 O(n)

比如:源二叉树
在这里插入图片描述

镜像二叉树
在这里插入图片描述

示例

示例1

输入:{8,6,10,5,7,9,11}
返回值:{8,10,6,11,9,7,5}

说明:如题面所示

示例2

输入:{}
返回值:{}

题解

Java代码实现:

publicclassSolution{/**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pRoot TreeNode类 
     * @return TreeNode类
     */publicTreeNodeMirror(TreeNode pRoot){// write code hereif(pRoot ==null)returnnull;// 构建辅助栈Stack<TreeNode> stack =newStack<>();// 根节点入栈
        stack.add(pRoot);while(!stack.isEmpty()){// 节点出栈TreeNode node = stack.pop();// 根节点的左右子树入栈if(node.left !=null) stack.add(node.left);if(node.right !=null) stack.add(node.right);// 左右子树交换TreeNode tmp = node.left;
            node.left = node.right;
            node.right = tmp;}return pRoot;}}

思路:主要是利用栈(或队列)遍历树的所有节点 node ,并交换每个 node 的左 / 右子节点。


问题4:重建二叉树

👉原题:重建二叉树

在这里插入图片描述

描述

给定节点数为 n 的二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。

例如输入前序遍历序列

{1,2,4,7,3,5,6,8}

和中序遍历序列

{4,7,2,1,5,3,8,6}

,则重建出如下图所示。

在这里插入图片描述

提示:

  1. vin.length == pre.length
    

2.pre 和 vin 均无重复元素
3.vin出现的元素均出现在 pre里
4.只需要返回根结点,系统会自动输出整颗树做答案对比

数据范围:n≤2000,节点的值 −10000≤val≤10000

要求:空间复杂度 O(n),时间复杂度 O(n)

示例

示例1

输入:[1,2,4,7,3,5,6,8],[4,7,2,1,5,3,8,6]
返回值:{1,2,3,4,#,5,6,#,7,#,#,8}

说明:返回根节点,系统会输出整颗二叉树对比结果,重建结果如题面图示

示例2

输入:[1],[1]
返回值:{1}

示例3

输入:[1,2,3,4,5,6,7],[3,2,4,1,6,5,7]
返回值:{1,2,5,3,4,6,7}

题解

Java代码实现:

publicclassSolution{publicTreeNodereConstructBinaryTree(int[] pre,int[] in){returndfs(0,0, in.length -1, pre, in);}publicTreeNodedfs(int preStart,int inStart,int inEnd,int[] preorder,int[] inorder){if(preStart > preorder.length -1|| inStart > inEnd){returnnull;}//创建结点TreeNode root =newTreeNode(preorder[preStart]);int index =0;//找到当前节点root在中序遍历中的位置,然后再把数组分两半for(int i = inStart; i <= inEnd; i++){if(inorder[i]== root.val){ index = i;break;}} root.left =dfs(preStart +1, inStart, index -1, preorder, inorder); root.right =dfs(preStart + index - inStart +1, index +1, inEnd, preorder, inorder);return root;}

思路:二叉树的前序遍历:根左右;中序遍历:左根右。设置三个指针,一个是preStart,表示的是前序遍历开始的位置,一个是inStart,表示的是中序遍历开始的位置。一个是inEnd,表示的是中序遍历结束的位置,我们主要是对中序遍历的数组进行拆解


问题5:二叉搜索树与双向链表

👉原题:二叉搜索树与双向链表

在这里插入图片描述

描述

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示

在这里插入图片描述

数据范围:输入二叉树的节点数 0≤n≤1000,二叉树中每个节点的值 0≤val≤1000

要求:空间复杂度O(1)(即在原树上操作),时间复杂度 O(n)

注意:

1.要求不能创建任何新的结点,只能调整树中结点指针的指向。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继
2.返回链表中的第一个节点的指针
3.函数返回的TreeNode,有左右指针,其实可以看成一个双向链表的数据结构
4.你不用输出双向链表,程序会根据你的返回值自动打印输出

输入描述: 二叉树的根节点
返回值描述: 双向链表的其中一个头节点。

示例

示例1

输入:{10,6,14,4,8,12,16}
返回值:From left to right are:4,6,8,10,12,14,16;From right to left are:16,14,12,10,8,6,4;

说明:输入题面图中二叉树,输出的时候将双向链表的头节点返回即可。

示例2

输入:{5,4,#,3,#,2,#,1}
返回值:From left to right are:1,2,3,4,5;From right to left are:5,4,3,2,1;

题解

Java代码实现:

publicclassSolution{TreeNode pre=null;TreeNode root=null;publicTreeNodeConvert(TreeNode pRootOfTree){if(pRootOfTree==null)returnnull;// 递归遍历左子树Convert(pRootOfTree.left);// 判断特殊情况if(root==null){
            root=pRootOfTree;}// 修改遍历的结点为双向链表if(pre!=null){
            pRootOfTree.left=pre;
            pre.right=pRootOfTree;}// 更新 pre
        pre=pRootOfTree;// 递归遍历右子树Convert(pRootOfTree.right);return root;}}

本文转载自: https://blog.csdn.net/zhangxia_/article/details/127267695
版权归原作者 橙子! 所有, 如有侵权,请联系我们删除。

“5道真题训练|学会了二叉树的前世今生(二)”的评论:

还没有评论