Lintcode: Subtree

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.

Have you met this question in a real interview? Yes
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
Note
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.

方法1: Traverse the tree T in preorder fashion. For every visited node in the traversal, see if the subtree rooted with this node is identical to S.

Time Complexity: Time worst case complexity of above solution is O(mn) where m and n are number of nodes in given two trees.

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

方法2:

 In this post a O(n) solution is discussed. The idea is based on the fact that inorder and preorder/postorder uniquely identify a binary tree. Tree S is a subtree of T if both inorder and preorder traversals of S arew substrings of inorder and preorder traversals of T respectively.

Following are detailed steps.

1) Find inorder and preorder traversals of T, store them in two auxiliary arrays inT[] and preT[].

2) Find inorder and preorder traversals of S, store them in two auxiliary arrays inS[] and preS[].

3) If inS[] is a subarray of inT[] and preS[] is a subarray preT[], then S is a subtree of T. Else not.

We can also use postorder traversal in place of preorder in the above algorithm.

Time Complexity: Inorder and Preorder traversals of Binary Tree take O(n) time. The function strstr() can also be implemented in O(n) time using KMP string matching algorithm.

Auxiliary Space: O(n)

可惜没有过Lintcode big case 

 1 /**
 2  * Definition of TreeNode:
 3  * public class TreeNode {
 4  *     public int val;
 5  *     public TreeNode left, right;
 6  *     public TreeNode(int val) {
 7  *         this.val = val;
 8  *         this.left = this.right = null;
 9  *     }
10  * }
11  */
12 public class Solution {
13     /**
14      * @param T1, T2: The roots of binary tree.
15      * @return: True if T2 is a subtree of T1, or false.
16      */
17     public boolean isSubtree(TreeNode T1, TreeNode T2) {
18         // write your code here
19         if (T2 == null) return true;
20         if (T1 == null) return false;
21         StringBuffer in1 = new StringBuffer();
22         StringBuffer in2 = new StringBuffer();
23         inorder(in1, T1);
24         inorder(in2, T2);
25         StringBuffer pre1 = new StringBuffer();
26         StringBuffer pre2 = new StringBuffer();
27         preorder(pre1, T1);
28         preorder(pre2, T2);
29         return isSubstring(in2.toString(), in1.toString()) && isSubstring(pre2.toString(), pre1.toString());
30     }
31     
32     public void inorder(StringBuffer sb, TreeNode cur) {
33         if (cur == null) return;
34         inorder(sb, cur.left);
35         sb.append(cur.val);
36         inorder(sb, cur.right);
37     }
38     
39     public void preorder(StringBuffer sb, TreeNode cur) {
40         if (cur == null) return;
41         sb.append(cur.val);
42         preorder(sb, cur.left);
43         preorder(sb, cur.right);
44     }
45     
46     public boolean isSubstring(String str2, String str1) {
47         for (int i=0; i<=str1.length()-str2.length(); i++) {
48             String sub = str1.substring(i, i+str2.length());
49             if (sub.equals(str2)) return true;
50         }
51         return false;
52     }
53 }

 

转载于:https://www.cnblogs.com/EdwardLiu/p/5185350.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值