Skip to content

Latest commit

 

History

History
161 lines (136 loc) · 5.2 KB

LeetCode 0572. 另一棵树的子树.md

File metadata and controls

161 lines (136 loc) · 5.2 KB

题目链接: https://leetcode.cn/problems/subtree-of-another-tree/

视频题解: https://www.bilibili.com/video/BV1BseceLE6R/

LeetCode 572. 另一棵树的子树

题目描述

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

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

举个例子:

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

思路解析

首先明确子树的概念,对于下图,subRoot中节点虽然和root中节点的值相等,但是subRoot节点2的左孩子是NULLroot节点2的左孩子是节点0,这违反了结构相同,所以subRoot不是root的子树。

明确了子树的概念,此问题的递归步骤如下:

  1. rootsubRoot是否相等(root本身也是自己的子树)。
  2. subRoot是否是root->left的子树。
  3. subRoot是否是root->right的子树。

上述三个点只要有一点成立,就说明subRootroot的子树。

C++代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool isSubtree(TreeNode* root, TreeNode* subRoot) {
        //递归结束的条件,空节点NULL是任意树的子树
        if (!subRoot) return true;
        //递归结束的条件,此时subRoot不为NULL
        if (!root) return false;
        //递归结束的条件
        if (isSameTree(root, subRoot)) return true;
        //子问题
        return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
    }

    bool isSameTree(TreeNode* p, TreeNode* q) {
        //递归结束的条件
        if (!p && !q) {
            return true;
        }
        //递归结束的条件
        if (!p || !q || p->val != q->val) {
            return false;
        }
        //子问题
        return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
    }
};

java代码

/**
 * 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) {
          // 递归结束的条件,空节点null是任意树的子树
        if (subRoot == null) return true;
        // 递归结束的条件,此时subRoot不为null
        if (root == null) return false;
        // 递归结束的条件
        if (isSameTree(root, subRoot)) return true;
        // 子问题
        return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);
    }

    public boolean isSameTree(TreeNode p, TreeNode q) {
        // 递归结束的条件
        if (p == null && q == null) {
            return true;
        }
        // 递归结束的条件
        if (p == null || q == null || p.val != q.val) {
            return false;
        }
        // 子问题
        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }
}

python代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:
         # 递归结束的条件,空节点None是任意树的子树
        if not subRoot:
            return True
        # 递归结束的条件,此时subRoot不为None
        if not root:
            return False
        # 递归结束的条件
        if self.isSameTree(root, subRoot):
            return True
        # 子问题
        return self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)

    def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
        # 递归结束的条件
        if not p and not q:
            return True
        # 递归结束的条件
        if not p or not q or p.val != q.val:
            return False
        # 子问题
        return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)

复杂度分析

时间复杂度: 由于s的每一个节点都要与t进行去匹配,所以时间复杂度为 O(ST),其中Ss的节点数量,Tt的节点数量。

空间复杂度: 匹配的过程用到了递归,递归会用到函数栈,栈的最大长度基本和t的高度一致,故空间复杂度和t的高度相关。