• 二叉树习题-小记


    二叉树

    二叉树知识点

    在这里插入图片描述
    6.偶数个结点:n1=1;奇数个结点n1=0
    在这里插入图片描述

    相同的树

    相同的树
    给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。

    如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

    示例 1:
    在这里插入图片描述

    输入:p = [1,2,3], q = [1,2,3]
    输出:true

    示例 2:
    在这里插入图片描述

    输入:p = [1,2], q = [1,null,2]
    输出:false

    思路:

    1. 判断根节点(结构和值)
    2. 递归结点p的左树和结点q的左树;
      递归结点p的右树和结点q的右树
    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        public boolean isSameTree(TreeNode p, TreeNode q) {
            if(p!=null&&q==null||p==null&&q!=null){
                return false;
            }
            if(p==null&&q==null){
                return true;
            }
            //p\q都不为null
            if(p.val!=q.val){
                return false;
            }
            return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
            
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    572. 另一棵树的子树

    另一棵树的子树
    给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。

    二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

    示例 1:
    在这里插入图片描述

    输入:root = [3,4,5,1,2], subRoot = [4,1,2]
    输出:true

    示例 2:
    在这里插入图片描述

    输入:root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
    输出:false

    思路:

    1. 判断 subRoot是不是和root相同
    2. subRoot是不是root的左子树
    3. subRoot是不是root的右子树
    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        public boolean isSubtree(TreeNode root, TreeNode subRoot) {
            if(root==null||subRoot==null){
                return false;
            }
            if(isSameTree(root,subRoot)) return true;
            if(isSubtree(root.left,subRoot)) return true;
            if(isSubtree(root.right,subRoot)) return true;
            return false;
        }
        public boolean isSameTree(TreeNode p, TreeNode q) {
            if(p!=null&&q==null||p==null&&q!=null){
                return false;
            }
            if(p==null&&q==null){
                return true;
            }
            //p\q都不为null
            if(p.val!=q.val){
                return false;
            }
            return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    110. 平衡二叉树

    平衡二叉树
    给定一个二叉树,判断它是否是高度平衡的二叉树。

    本题中,一棵高度平衡二叉树定义为:

    一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

    示例 1:
    在这里插入图片描述

    输入:root = [3,9,20,null,null,15,7]
    输出:true

    示例 2:
    在这里插入图片描述

    输入:root = [1,2,2,3,3,null,null,4,4]
    输出:false

    示例 3:

    输入:root = []
    输出:true

    思路:
    平衡:每棵子树左右高度差不能超过1

    • root平衡
    • root.left平衡
    • root.right 平衡
      在计算高度时,判断当前的结点是否平衡,若不平衡,向上返回-1.
    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        public boolean isBalanced(TreeNode root) {
            return maxDepth(root)>=0;
        }
        public int maxDepth(TreeNode root){
            if(root==null){
                return 0;
            }
            int leftH=maxDepth(root.left);
            int leftR=maxDepth(root.right);
    
            //一个结点左右子树遍历完
            if(leftH>=0&&leftR>=0&&Math.abs(leftH-leftR)<=1){
                return Math.max(leftH,leftR)+1;
            }else{
                return -1;//说明不平衡
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    101. 对称二叉树

    对称二叉树

    给你一个二叉树的根节点 root , 检查它是否轴对称。

    示例 1:
    在这里插入图片描述

    输入:root = [1,2,2,3,4,4,3]
    输出:true

    示例 2:
    在这里插入图片描述

    输入:root = [1,2,2,null,3,null,3]
    输出:false

    思路:

    1. 判断左树右树是不是对称的
    2. 判断时存在以下情况
    • 1.一个为空,一个不为空
    • 2.两个都为空
    • 3.值是不是一样的
    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        public boolean isSymmetric(TreeNode root) {
            if(root==null){
                return true;
            }
            //判断左树右树是不是对称的
            return isSymmetricChild(root.left,root.right);
    
        }
        public boolean isSymmetricChild(TreeNode leftTree,TreeNode rightTree){
            //1.一个为空,一个不为空
            if(leftTree==null&&rightTree!=null||leftTree!=null&&rightTree==null){
                return false;
            }
            //2.两个都为空
            if(leftTree==null&&rightTree==null){
                return true;
            }
            //3.值是不是一样的
            if(leftTree.val==rightTree.val){
                return isSymmetricChild(leftTree.left,rightTree.right)&&isSymmetricChild(leftTree.right,rightTree.left);
            }
            return false;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    236. 二叉树的最近公共祖先

    二叉树的最近公共祖先

    思路:

    1. 若p、q在root的左右两边,则root为最近公共祖先。
    2. 若p、q同在左子树,或同在右子树中,则搜索到的返回的第一个结点即为最近公共祖先。
    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            if(root==null){
                return null;
            }
            if(root==p||root==q){
                return root;
            }
            TreeNode leftTree=lowestCommonAncestor(root.left,p,q);
            TreeNode rightTree=lowestCommonAncestor(root.right,p,q);
            if(leftTree!=null&&rightTree!=null){
                return root;
            }
            if(leftTree!=null&&rightTree==null){
                return leftTree;
            }
            if(leftTree==null&&rightTree!=null){
                return rightTree;
            }
            return null;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    1.还可以使用 两个链表求交点(p到公共祖先、q到公共祖先看作两个链表),但前提是每个节点需包含parent域。
    2.利用栈,从root节点到p的所有节点插入栈1中,从root节点到q的所有节点放入栈2中,根据栈1和栈2中size的差值,将栈元素数量多的栈元素弹出,直到两个栈中元素数量一致;然后栈1和栈2同时弹出元素,直到弹出的元素相等,即为 【最近公共祖先】

    JZ36 二叉搜索树与双向链表

    JZ36 二叉搜索树与双向链表

    描述
    输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示
    在这里插入图片描述
    数据范围:输入二叉树的节点数 0≤n≤1000,二叉树中每个节点的值 0≤val≤1000
    要求:空间复杂度O(1)(即在原树上操作),时间复杂度 O(n)

    /**
    public class TreeNode {
        int val = 0;
        TreeNode left = null;
        TreeNode right = null;
    
        public TreeNode(int val) {
            this.val = val;
    
        }
    
    }
    */
    public class Solution {
        public TreeNode prev=null;
        public TreeNode Convert(TreeNode pRootOfTree) {
            if(pRootOfTree==null){
                return null;
            }
            ConvertChild(pRootOfTree);
    
            TreeNode head=pRootOfTree;
            while(head.left!=null){
                head=head.left;
            }
            return head;
        }
        public void ConvertChild(TreeNode pCur){
            if(pCur==null){
                return ;
            }
            ConvertChild(pCur.left);
            pCur.left=prev;
            if(prev!=null){
                prev.right=pCur;
            }
            prev=pCur;
            ConvertChild(pCur.right);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    105. 从前序与中序遍历序列构造二叉树

    从前序与中序遍历序列构造二叉树
    关键在于通过preorder得知根结点,在inorder 中找到根节点下标,以此划分左右子树,再根据左右子树下标区间进行递归,来构造二叉树。

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        public int preIndex=0;
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            return buildTreeChild(preorder,inorder,0,inorder.length-1);
        }
        public TreeNode buildTreeChild(int[] preorder,int[] inorder,int inbegin,int inend){
            if(inbegin>inend){
                return null;//说明没有左树 或者 没有右树
            }
            TreeNode root=new TreeNode(preorder[preIndex]);
    
            int rootIndex=findIndex(inorder,preorder[preIndex],inbegin,inend);
            preIndex++;
            root.left=buildTreeChild(preorder,inorder,inbegin,rootIndex-1);
            root.right=buildTreeChild(preorder,inorder,rootIndex+1,inend);
            return root;
        }
        public int findIndex(int[] inorder,int key,int inbegin,int inend){
            for(int i=inbegin;i<=inend;i++){
                if(inorder[i]==key){
                    return i;
                }
            }
            return -1;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    同理106. 从中序与后序遍历序列构造二叉树
    从中序与后序遍历序列构造二叉树

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        public int postIndex=0;
        public TreeNode buildTree(int[] inorder, int[] postorder) {
            postIndex=postorder.length-1;
            return buildTreeChild(inorder,0,inorder.length-1,postorder);
        }
        public TreeNode buildTreeChild(int[] inorder,int inbegin,int inend,int[] postorder){
            if(inbegin>inend){
                return null;
            }
            TreeNode root=new TreeNode(postorder[postIndex]);
    
            int rootIndex=findIndex(inorder,inbegin,inend,postorder[postIndex]);
            postIndex--;
            root.right=buildTreeChild(inorder,rootIndex+1,inend,postorder);
            root.left=buildTreeChild(inorder,inbegin,rootIndex-1,postorder);
            return root;
        }
        public int findIndex(int[] inorder,int inbegin,int inend,int key){
            for(int i=inbegin;i<=inend;i++){
                if(inorder[i]==key){
                    return i;
                }
            }
            return -1;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    606 根据二叉树创建字符串

    根据二叉树创建字符串

    给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。

    空节点使用一对空括号对 “()” 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。

    给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。

    空节点使用一对空括号对 “()” 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。

    示例 1:
    在这里插入图片描述

    输入:root = [1,2,3,4]
    输出:“1(2(4))(3)”
    解释:初步转化后得到 “1(2(4)())(3()())” ,但省略所有不必要的空括号对后,字符串应该是"1(2(4))(3)" 。

    示例 2:
    在这里插入图片描述

    输入:root = [1,2,3,null,4]
    输出:“1(2()(4))(3)”
    解释:和第一个示例类似,但是无法省略第一个空括号对,否则会破坏输入与输出一一映射的关系。

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        public String tree2str(TreeNode root) {
            StringBuilder sb=new StringBuilder();
            if(root==null){
                return sb.toString();
            }
            tree2strChild(root,sb);
            return new String(sb);
        }
        public void tree2strChild(TreeNode t,StringBuilder sb){
            if(t==null){
                return ;
            }
            sb.append(t.val);//根  左  右
            if(t.left!=null){
                sb.append("(");
                tree2strChild(t.left,sb);
                sb.append(")");
            }else{
                if(t.right==null){
                    return;
                }else{
                    sb.append("()");
                }
            }
            if(t.right==null){
                return;
            }else{
                sb.append("(");
                tree2strChild(t.right,sb);
                sb.append(")");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
  • 相关阅读:
    中兴设备18种命令模式总结大全,全网第一篇,强烈建议收藏!
    SpringBoot整合其它项目
    Java Fork/Join 并发编程
    asp.net教务管理信息系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio计算机毕业设计
    vue中转换base64文件数据后通过blob下载
    Github 快速访问常见方法
    HarmonyOS 管理页面跳转及浏览记录导航
    Error-onnxruntime.capi.onnxruntime_pybind11_state.Fail:
    基于SpringBoot的知识管理系统
    《MongoDB入门教程》第07篇 CRUD之查找文档
  • 原文地址:https://blog.csdn.net/xy199931/article/details/127845049