剑指Offer-树的子结构

83 阅读2分钟

题目

输入两棵二叉树 A,BA,B,判断 BB 是不是 AA 的子结构。

我们规定空树不是任何树的子结构。

数据范围

每棵树的节点数量 [0,1000][0,1000]。

样例

树 AA:

     8
    / \
   8   7
  / \
 9   2
    / \
   4   7

树 BB:

   8
  / \
 9   2

返回 true,因为 BB 是 AA 的子结构。

解析(来自y总)

代码分为两个部分:

遍历树A中的所有非空节点R; 判断树A中以R为根节点的子树是不是包含和树B一样的结构,且我们从根节点开始匹配; 对于第一部分,我们直接递归遍历树A即可,遇到非空节点后,就进行第二部分的判断。

对于第二部分,我们同时从根节点开始遍历两棵子树:

如果树B中的节点为空,则表示当前分支是匹配的,返回true; 如果树A中的节点为空,但树B中的节点不为空,则说明不匹配,返回false; 如果两个节点都不为空,但数值不同,则说明不匹配,返回false; 否则说明当前这个点是匹配的,然后递归判断左子树和右子树是否分别匹配即可;

代码

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 hasSubtree(TreeNode* pRoot1, TreeNode* pRoot2) {
        if (!pRoot1 || !pRoot2)
            return false;
        if (isMatch(pRoot1, pRoot2)) return true;
        return hasSubtree(pRoot1->left, pRoot2) || hasSubtree(pRoot1->right, pRoot2);
    }
    
    bool isMatch(TreeNode* A, TreeNode* B) {
        if (!B) return true;
        if (!A || A->val != B->val) return false;
        return isMatch(A->left, B->left) && isMatch(A->right, B->right);
    }
};

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 hasSubtree(self, pRoot1, pRoot2):
        """
        :type pRoot1: TreeNode
        :type pRoot2: TreeNode
        :rtype: bool
        """
        def isMatch(A, B):
            if B is None:
                return True
            if A is None or A.val != B.val:
                return False
            return isMatch(A.left, B.left) and isMatch(A.right, B.right)
        
        if pRoot1 is None or pRoot2 is None:
            return False
        if isMatch(pRoot1, pRoot2):
            return True
        return self.hasSubtree(pRoot1.left, pRoot2) or self.hasSubtree(pRoot1.right, pRoot2)

GO

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func hasSubtree(pRoot1 *TreeNode, pRoot2 *TreeNode) bool {
    if pRoot1 == nil || pRoot2 == nil {
        return false
    }
    if isMatch(pRoot1,pRoot2) {
        return true
    }
    return hasSubtree(pRoot1.Left,pRoot2) || hasSubtree(pRoot1.Right,pRoot2)
}

func isMatch(pRoot1 *TreeNode, pRoot2 *TreeNode) bool {
    if pRoot2 == nil {
        return true
    }
    if pRoot1 == nil || pRoot1.Val != pRoot2.Val {
        return false
    }
    return isMatch(pRoot1.Left,pRoot2.Left) && isMatch(pRoot1.Right,pRoot2.Right)
}