美文网首页
26. 树的子结构

26. 树的子结构

作者: 木木与呆呆 | 来源:发表于2022-03-21 15:08 被阅读0次

    链接

    https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof/
    难度: #中等

    题目

    输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)

    B是A的子结构, 即 A中有出现和B相同的结构和节点值。

    例如:
    给定的树 A:

         3
        / \
       4   5
      / \
     1   2
    

    给定的树 B:

       4 
      /
     1
    

    返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。

    示例 1:

    输入:A = [1,2,3], B = [3,1]
    输出:false
    

    示例 2:

    输入:A = [3,4,5,1,2], B = [4,1]
    输出:true
    

    限制:
    0 <= 节点个数 <= 10000

    代码框架

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        public boolean isSubStructure(TreeNode A, TreeNode B) {
    
        }
    }
    

    题目解析

    1.创建一个辅助函数判断两棵树是否相等
    2.递归遍历A树的每一个节点作为根结点和B树进行比较
    3.每次遇到A的节点与B的头结点相同,则继续比较A和B的子节点

    解答思路1:
    在二叉树A中先序遍历,
    找到第一个和B的第一个相同的节点,
    然后比较其左右子节点是否相同,
    如果B没有左或者右节点,则无需比较,
    直接返回true,
    如果A没有子节点,B有子节点,则一定不是,
    直接返回false。

    解答思路2:
    解答思路1的代码优化写法,
    利用了&&和||逻辑运算符的快速返回特性,
    在二叉树A中先序遍历,
    找到第一个和B的第一个相同的节点,
    然后比较其左右子节点是否相同,
    如果B没有左或者有节点,则无需比较。

    测试用例

    package edu.yuwen.sowrd.num26.solution;
    
    import org.junit.jupiter.api.Assertions;
    import org.junit.jupiter.api.Test;
    
    import edu.yuwen.sowrd.entity.TreeNode;
    import edu.yuwen.sowrd.num26.sol1.Solution;
    
    public class SolutionTest {
    
        /**
         * 示例 1:
         * 输入:A = [1,2,3], B = [3,1]
         * 输出:false
         */
        @Test
        public void testCase1() {
            Solution solution = new Solution();
            TreeNode a = getTreeNodeA1();
            TreeNode b = getTreeNodeB1();
            boolean res = solution.isSubStructure(a, b);
            Assertions.assertEquals(false, res);
        }
    
        /**
         * 示例 2:
         * 输入:A = [3,4,5,1,2], B = [4,1]
         * 输出:true
         */
        @Test
        public void testCase2() {
            Solution solution = new Solution();
            TreeNode a = getTreeNodeA2();
            TreeNode b = getTreeNodeB2();
            boolean res = solution.isSubStructure(a, b);
            Assertions.assertEquals(true, res);
        }
    
        /**
         *       1
         *      / \
         *     2   3
         */
        public TreeNode getTreeNodeA1() {
            TreeNode node1 = new TreeNode(1);
            TreeNode node2 = new TreeNode(2);
            TreeNode node3 = new TreeNode(3);
    
            node1.left = node2;
            node1.right = node3;
    
            return node1;
        }
    
        /**
         *       3
         *      / 
         *     1   
         */
        public TreeNode getTreeNodeB1() {
            TreeNode node1 = new TreeNode(3);
            TreeNode node2 = new TreeNode(1);
    
            node1.left = node2;
            return node1;
        }
    
        /**
         *     3
         *    / \
         *   4   5
         *  / \
         * 1   2
         */
        public TreeNode getTreeNodeA2() {
            TreeNode node1 = new TreeNode(3);
            TreeNode node2 = new TreeNode(4);
            TreeNode node3 = new TreeNode(5);
            TreeNode node4 = new TreeNode(1);
            TreeNode node5 = new TreeNode(2);
    
            node1.left = node2;
            node1.right = node3;
    
            node2.left = node4;
            node2.right = node5;
    
            return node1;
        }
    
        /**
         *       4
         *      / 
         *     1   
         */
        public TreeNode getTreeNodeB2() {
            TreeNode node1 = new TreeNode(4);
            TreeNode node2 = new TreeNode(1);
    
            node1.left = node2;
            return node1;
        }
    }
    

    解答1

    package edu.yuwen.sowrd.num26.sol1;
    
    import edu.yuwen.sowrd.entity.TreeNode;
    
    public class Solution {
        public boolean isSubStructure(TreeNode a, TreeNode b) {
            if (a == null || b == null) {
                return false;
            }
    
            // 比较当前节点及其子节点
            boolean cur = compare(a, b);
            // 确定是子结构即可返回
            if (cur) {
                return true;
            }
    
            // 否则遍历左右子树
            if (a.left != null) {
                boolean left = isSubStructure(a.left, b);
                // 只要相等了,即可返回
                if (left) {
                    return true;
                }
            }
    
            if (a.right != null) {
                boolean right = isSubStructure(a.right, b);
                if (right) {
                    return true;
                }
            }
    
            return false;
        }
    
        // 比较两颗二叉树是否相同
        private boolean compare(TreeNode a, TreeNode b) {
            // base case
            if (a == null) {
                if (b == null) {
                    return true;
                }
                return false;
            }
    
            if (a != null && b == null) {
                return true;
            }
    
            // 比较当前值
            boolean cur = a.val == b.val;
            // 只要有一个节点不同,即可返回
            if (!cur) {
                return false;
            }
    
            // 比较左节点
            boolean left = compare(a.left, b.left);
            if (!left) {
                return false;
            }
    
            // 比较右节点
            boolean right = compare(a.right, b.right);
            if (!right) {
                return false;
            }
    
            // 当前和左右节点都相同,才认为相同
            return true;
        }
    }
    

    解答2 推荐

    package edu.yuwen.sowrd.num26.sol2;
    
    import edu.yuwen.sowrd.entity.TreeNode;
    
    public class Solution {
        public boolean isSubStructure(TreeNode a, TreeNode b) {
            if (a == null || b == null) {
                return false;
            }
    
            // 先序遍历二叉树A, 比较当前节点及其子节点
            // 确定是子结构即可返回
            // 否则遍历二叉树a下一个节点
            return compare(a, b) || isSubStructure(a.left, b)
                    || isSubStructure(a.right, b);
        }
    
        // 比较两颗二叉树是否相同
        private boolean compare(TreeNode a, TreeNode b) {
            // base case
            // b为null,则一定相同
            if (b == null) {
                return true;
            }
            // b不为null,但a为null,则一定不同
            else if (a == null) {
                return false;
            }
    
            // 比较当前值, 比较左节点,比较右节点
            // 当前和左右节点都相同,才认为相同
            // 否则只要有一个节点不同,即可返回
            return a.val == b.val && compare(a.left, b.left)
                    && compare(a.right, b.right);
        }
    }
    

    相关文章

      网友评论

          本文标题:26. 树的子结构

          本文链接:https://www.haomeiwen.com/subject/oshtjrtx.html