树的子结构(剑指offer 26)Java先序遍历+子结构判断

简介: 输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)B是A的子结构, 即 A中有出现和B相同的结构和节点值。

一、题目描述



输入两棵二叉树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


二、思路讲解


       

判断B是否是A的子结构,毫无疑问是要遍历A的,关键在于如何分解子问题,再递归求解。

       

我们可以用函数isSubStructure(A,B)来先序遍历A,用函数fun(A,B)来判断A中是否含有B。


那么,我们就先序遍历A,然后判断B是否在A中。


看一下fun函数的终止条件:


1、B == null        说明B已经穿过叶子节点,没有出现问题,说明B是A的子结构,返回true;


2、A == null        说明A已经穿过了叶子节点,还是没有找到能够返回true的条件(和B相同的结构),说明应该返回false;


3、A.val != B.val        说明A的根节点与B的根节点值不相同,返回false


没有出现以上三种情况,说明遍历到目前为止,A的结构中目前可能存在B相同的结构,至于是否真的存在B这样的结构,还需要看看A的左子树和B的左子树、A的右子树和B的右子树是否有相同结构,fun(A.left, B.left),fun(A.right, B.right)


再看一下isSubStructure的终止条件:


1、A==null || B==null        说明一直找到A或者B的根节点都没有找到相同结构,返回false


或者说明A或B本身就是空树,返回false


2、A中有B的结构,或者A的左子树中有B的结构,或者A的右子树中有B的结构(先序遍历A),只要满足一个就返回true,否则返回false。


三、Java代码实现



/**
 * 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) {
        //已经穿过叶子节点,说明整棵树中没有符合的结构
        //或者本身就是空树
        if(A==null || B==null){
            return false;
        }
        //如果B是A的子结构  或者B是A的左子树的子结构  或者B是A的右子树的子结构
        //三个条件满足其中一个则返回true,都不满足则返回false(也就是先序遍历A)
        return fun(A, B)||isSubStructure(A.left, B)||isSubStructure(A.right, B);
    }
    //判断B是否是A的子结构
    public static boolean fun(TreeNode A, TreeNode B){
        //如果B为空,说明此时已经穿过了B的叶子节点,B是A的子结构
        if(B == null){
            return true;
        }
        //如果A为空,说明此时已经传过了A的叶子节点,说明A中没有与B相同的结构
        //如果A的值与B不相等,说明不符合条件
        if(A == null || A.val!=B.val){
            return false;
        }
        //能够到达这一步说明A和B的值相同,那就再比较左右子树是否相同
        return fun(A.left, B.left) && fun(A.right, B.right);
    }
}


四、时空复杂度分析


     

看一下力扣大佬的复杂度分析:


6d7c7029a138434b92015c6a65583567.png



相关文章
|
5月前
|
存储 算法 Java
Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。
【6月更文挑战第21天】Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。二叉树遍历通过访问根、左、右子节点实现。DFS采用递归遍历图的节点,而BFS利用队列按层次访问。以下是简化的代码片段:[Java代码略]
45 4
|
6月前
|
Java
Tree Traversals Again(Java语言)(先序和中序创建二叉树)(遍历树)
Tree Traversals Again(Java语言)(先序和中序创建二叉树)(遍历树)
40 4
|
3月前
|
存储 Java
|
3月前
|
存储 Java
|
5月前
|
存储 安全 Java
深入解析Java HashMap的高性能扩容机制与树化优化
深入解析Java HashMap的高性能扩容机制与树化优化
145 1
|
5月前
|
Java
JAVA中的AVL树实现
JAVA中的AVL树实现
48 1
|
5月前
|
Java
赫夫曼树(java)
赫夫曼树(java)
|
5月前
|
Java
剑指offer_3_前n个数字二进制形式中1的个数(java)
剑指offer_3_前n个数字二进制形式中1的个数(java)
|
5月前
|
Java
剑指offer_2_二进制加法(java)
剑指offer_2_二进制加法(java)
|
5月前
|
Java
剑指offer_1_整数除法(java)
剑指offer_1_整数除法(java)