本问题对应的 leetcode 原文链接:剑指 Offer 26. 树的子结构

问题描述

输入两棵二叉树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 <= 节点个数 <= 100000

解题思路

视频讲解直达: 本题视频讲解

代码实现

class Solution {
    public boolean isSubStructure(TreeNode A, TreeNode B) {
        if(A == null || B == null){
            return false;
        }

        if(isSubTree(A, B)){
            return true;
        }

        if(isSubStructure(A.left, B) || isSubStructure(A.right, B)){
            return true;
        }

        return false;
    }

    public boolean isSubTree(TreeNode Ta, TreeNode Tb){
        if(Tb == null){
            return true;
        }

        if(Ta == null){
            return false;
        }

        if(Ta.val != Tb.val){
            return false;
        }

        return isSubTree(Ta.left, Tb.left) &&
               isSubTree(Ta.right, Tb.right);
    }
}

假设树A的节点个数为 n, 树B为k,则
时间复杂度:isSubTree函数的时间复杂度为 O(k),所以时间复杂度为 O(n*k)。
空间复杂度:空间复杂度为树 A 的高度。

Python

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def isSubStructure(self, A, B):
        """
        :type A: TreeNode
        :type B: TreeNode
        :rtype: bool
        """
        if A is None or B is None:
            return False

        if self.isSubTree(A, B):
            return True

        if self.isSubStructure(A.left, B) or self.isSubStructure(A.right, B):
            return True

        return False

    def isSubTree(self, Ta, Tb):
        if Tb is None:
            return True

        if Ta is None:
            return False

        if Ta.val != Tb.val:
            return False

        return self.isSubTree(Ta.left, Tb.left) and self.isSubTree(Ta.right, Tb.right)

C++

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isSubStructure(TreeNode* A, TreeNode* B) {
        if (A == nullptr || B == nullptr) {
            return false;
        }

        if (isSubTree(A, B)) {
            return true;
        }

        if (isSubStructure(A->left, B) || isSubStructure(A->right, B)) {
            return true;
        }

        return false;
    }

    bool isSubTree(TreeNode* Ta, TreeNode* Tb) {
        if (Tb == nullptr) {
            return true;
        }

        if (Ta == nullptr) {
            return false;
        }

        if (Ta->val != Tb->val) {
            return false;
        }

        return isSubTree(Ta->left, Tb->left) && isSubTree(Ta->right, Tb->right);
    }
};

Go

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func isSubStructure(A *TreeNode, B *TreeNode) bool {
    if A == nil || B == nil {
        return false
    }

    if isSubTree(A, B) {
        return true
    }

    if isSubStructure(A.Left, B) || isSubStructure(A.Right, B) {
        return true
    }

    return false
}

func isSubTree(Ta *TreeNode, Tb *TreeNode) bool {
    if Tb == nil {
        return true
    }

    if Ta == nil {
        return false
    }

    if Ta.Val != Tb.Val {
        return false
    }

    return isSubTree(Ta.Left, Tb.Left) && isSubTree(Ta.Right, Tb.Right)
}

JS

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} A
 * @param {TreeNode} B
 * @return {boolean}
 */
var isSubStructure = function(A, B) {
    if (A == null || B == null) {
        return false;
    }

    if (isSubTree(A, B)) {
        return true;
    }

    if (isSubStructure(A.left, B) || isSubStructure(A.right, B)) {
        return true;
    }

    return false;
};

var isSubTree = function(Ta, Tb) {
    if (Tb == null) {
        return true;
    }

    if (Ta == null) {
        return false;
    }

    if (Ta.val != Tb.val) {
        return false;
    }

    return isSubTree(Ta.left, Tb.left) &&
           isSubTree(Ta.right, Tb.right);
};

发表回复

后才能评论

评论(4)

  • Yuki 永久会员 2024年3月8日 上午10:06

    时间复杂度:O(AB)
    空间复杂度:O(A)
    class Solution {
    public:
    bool isSubtree(TreeNode* A, TreeNode* B){
    //B是不是以A的根节点为根的子树

        //先判断根
        if(A==NULL||A->val!=B->val)return false;
        if(B==NULL)return true;
    
        //再判断左右子树
        return isSubtree(A->left,B->left)&&isSubtree(A->right,B->right);
    
    }
    
    bool isSubStructure(TreeNode* A, TreeNode* B) {
        if(A==NULL||B==NULL)return false;
    
        //是不是子树
        if(isSubtree(A,B))return true;
    
        //是不是A左右子树的子树
        if(isSubStructure(A->left,B)||isSubStructure(A->right,B))
            return true;
    
        return false;
    }
    

    };

  • Marshan 普通 2023年7月16日 上午11:17

    CPP代码目前无法通过leetcode测试用例

  • 优秀市民 普通 2022年10月28日 下午11:16
    class Solution {
        public boolean isSubStructure(TreeNode A, TreeNode B) {
    
            //遍历A中的每个节点,A树中任意节点包哈B就能返回true
            return  (A != null && B != null) && (re(A,B) || isSubStructure(A.left,B) || isSubStructure(A.right,B));
    
        }
        //以A为根的数是否包含B 从A开始
        public boolean re(TreeNode A, TreeNode B){
            if(B == null) return true;
            if(A == null || A.val != B.val) return false;
            return re(A.left,B.left) && re(A.right,B.right);
        }
    }
    

    omn
    om
    若B是A的字结构,则子结构的根节点可能是树A的任意一个节点,所以首先先序遍历树A中的每个节点 a,判断A种以 a 为根节点的子树是否包含树B