Subtree

Subtree

Description:

You have two every large binary trees: T1, with millions of nodes, and T2, with hundreds of nodes. Create an algorithm to decide if T2 is a subtree of T1.

Notice

A tree T2 is a subtree of T1 if there exists a node n in T1 such that the subtree of n is identical to T2. That is, if you cut off the tree at node n, the two trees would be identical.

Example:

T2 is a subtree of T1 in the following case:

       1                  3
      / \                / 
T1 = 2   3        T2 =  4
    /
   4

T2 isn’t a subtree of T1 in the following case:

       1               3
      / \               \
T1 = 2   3        T2 =   4
    /
   4

分析:

判断T2是否是T1的子树,首先应该在T1中找到T2的根节点,且两棵子树必须完全相同。所以整个思路分为两步走:找根节点,判断两棵树是否全等;若不等,则需要判断是否是左/右子树的子树。

注意递归的先后顺序:需要先调用identical(调用.val前需要判断是否为null),再递归调用isSubtree判断左/右子树的情况。

identical的调用,时间复杂度近似O(n), 查根节点的时间复杂度随机平均为O(m), 故总的时间复杂度可近似为O(mn)

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param T1, T2: The roots of binary tree.
* @return: True if T2 is a subtree of T1, or false.
*/
bool isSubtree(TreeNode *T1, TreeNode *T2) {
// write your code here
if (T2 == nullptr) return true;
if (T1 == nullptr) return false;

return identical(T1, T2) || isSubtree(T1->left, T2) || isSubtree(T1->right, T2);
}

bool identical(TreeNode *T1, TreeNode *T2) {
if (T1 == nullptr && T2 == nullptr) return true;
if (T1 == nullptr || T2 == nullptr) return false;
if (T1->val != T2->val) return false;

return identical(T1->left, T2->left) && identical(T1->right, T2->right);
}
};