题目:

有两个不同大小的二叉树: T1 有上百万的节点; T2 有好几百的节点。请设计一种算法,判定 T2 是否为 T1的子树。

样例

下面的例子中 T2 是 T1 的子树:

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

下面的例子中 T2 不是 T1 的子树:

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

若 T1 中存在从节点 n 开始的子树与 T2 相同,我们称 T2 是 T1 的子树。也就是说,如果在 T1 节点 n 处将砍断,砍断的部分将与 T2 完全相同。

解题:

感觉通过直接递归就可以解决,但是下面的程序运行到60%的测试数据结果就不对了

Java程序:

 

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */
public class Solution {
    /**
     * @param T1, T2: The roots of binary tree.
     * @return: True if T2 is a subtree of T1, or false.
     */
    public boolean isSubtree(TreeNode T1, TreeNode T2) {
        // write your code here
        if(T1==null && T2==null)
            return true;
        if(T1==null)
            return false;
        if(T2==null)
            return true;
        if(T1.val==T2.val&& T1.left==null && T2.left==null && T1.right==null && T2.right==null)
            return true;

        if(T1.val!=T2.val){
            boolean lft = isSubtree(T1.left,T2);
            boolean rit = isSubtree(T1.right,T2);
            if(lft || rit)
                return true;
        }else{
            boolean lft = isSubtree(T1.left,T2.left);
            boolean rit = isSubtree(T1.right,T2.right);
            if(lft && rit)
                return true;
        }
        return false;
    }
}
View Code

 

上面的程序中,当当前节点相同和不相同的时候,都是自身递归,在网上看到,对应节点相同的时候,要单独搞个递归判断

基本流程:

若T1.val!=T2.val,分布判断两个子树是否和T2相等,只有有一个相等就可以

若T1.val==T2.val,判断是否相等,若不相等,分布对其两个子树再判断

上面程序,可以感觉到走了个圈。

网上有的程序写的很简单。。。

Java程序:

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */
public class Solution {
    /**
     * @param T1, T2: The roots of binary tree.
     * @return: True if T2 is a subtree of T1, or false.
     */
    public boolean isSubtree(TreeNode T1, TreeNode T2) {
        // write your code here
        if(T1==null && T2==null)
            return true;
        if(T1==null)
            return false;
        if(T2==null)
            return true;

        if(T1.val!=T2.val){
            boolean lft = isSubtree(T1.left,T2);
            boolean rit = isSubtree(T1.right,T2);
            if(lft || rit)
                return true;
        }else{
            boolean res = isEqual(T1,T2);
            if(res)
                return true;
            else {
            boolean lft = isSubtree(T1.left,T2);
            boolean rit = isSubtree(T1.right,T2);
            if(lft || rit)
                return true;
            }
        }
        return false;
    }
    public boolean isEqual(TreeNode T1,TreeNode T2){
        if(T1==null && T2==null)
            return true;
        if(T1==null)
            return false;
        if(T2==null)
            return false;
        if(T1.val==T2.val){
            boolean lft = isEqual(T1.left,T2.left);
            boolean rit = isEqual(T1.right,T2.right);
            if(lft && rit)
                return true;
        }
        return false;
    }
}
View Code

总耗时: 5048 ms

上面的程序又部分冗余,现在修改如下,时间也少了好多

 

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */
public class Solution {
    /**
     * @param T1, T2: The roots of binary tree.
     * @return: True if T2 is a subtree of T1, or false.
     */
    public boolean isSubtree(TreeNode T1, TreeNode T2) {
        // write your code here
        if(T1==null && T2==null)
            return true;
        if(T1==null)
            return false;
        if(T2==null)
            return true;

        if(T1.val==T2.val){
            boolean res = isEqual(T1,T2);
            if(res)
                return true;
        }
        
        boolean lft = isSubtree(T1.left,T2);
        if(lft==true)
            return true;
        boolean rit = isSubtree(T1.right,T2);
        return rit;
    }
    public boolean isEqual(TreeNode T1,TreeNode T2){
        if(T1==null && T2==null)
            return true;
        if(T1==null)
            return false;
        if(T2==null)
            return false;
        if(T1.val==T2.val){
            boolean lft = isEqual(T1.left,T2.left);
            boolean rit = isEqual(T1.right,T2.right);
            if(lft && rit)
                return true;
        }
        return false;
    }
}
Java Code

 

总耗时: 3461 ms

 

Python程序:

"""
Definition of TreeNode:
class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left, self.right = None, None
"""
class Solution:
    # @param T1, T2: The roots of binary tree.
    # @return: True if T2 is a subtree of T1, or false.
    def isSubtree(self, T1, T2):
        # write your code here
        if(T1==None and T2==None):
            return True
        if T1==None:
            return False
        if T2==None:
            return True
        if T1.val!=T2.val:
            lft = self.isSubtree(T1.left,T2)
            rit = self.isSubtree(T1.right,T2)
            if lft or rit:
                return True
        else:
            res = self.isEqual(T1,T2)
            if res:
                return True
            else:
                lft = self.isSubtree(T1.left,T2)
                rit = self.isSubtree(T1.right,T2)
                if lft or rit:
                    return True
        return False
            
            
    def isEqual(self,T1,T2):
        
        if T1==None and T2==None:
            return True
        if T1==None:
            return False
        if T2==None:
            return False
        if T1!=None and T2!=None and T1.val==T2.val:
            lft = self.isEqual(T1.left,T2.left)
            rit = self.isEqual(T1.right,T2.right)
            if lft and rit:
                return True
        return False
View Code

总耗时: 640 ms