Subtree

Question

  1. You have two every large binary trees: T1,
  2. with millions of nodes, and T2, with hundreds of nodes.
  3. Create an algorithm to decide if T2 is a subtree of T1.
  4. Example
  5. T2 is a subtree of T1 in the following case:
  6. 1 3
  7. / \ /
  8. T1 = 2 3 T2 = 4
  9. /
  10. 4
  11. T2 isn't a subtree of T1 in the following case:
  12. 1 3
  13. / \ \
  14. T1 = 2 3 T2 = 4
  15. /
  16. 4
  17. Note
  18. A tree T2 is a subtree of T1 if there exists a node n in T1 such that
  19. the subtree of n is identical to T2.
  20. That is, if you cut off the tree at node n,
  21. the two trees would be identical.

题解

判断 T2是否是 T1的子树,首先应该在 T1中找到 T2的根节点,找到根节点后两棵子树必须完全相同。所以整个思路分为两步走:找根节点,判断两棵树是否全等。咋看起来极其简单,但实际实现中还是比较精妙的,尤其是递归的先后顺序及条件与条件或的处理。

Java

  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. if (T2 == null) return true;
  19. if (T1 == null) return false;
  20. return identical(T1, T2) || isSubtree(T1.left, T2) || isSubtree(T1.right, T2);
  21. }
  22. private boolean identical(TreeNode T1, TreeNode T2) {
  23. if (T1 == null && T2 == null) return true;
  24. if (T1 == null || T2 == null) return false;
  25. if (T1.val != T2.val) return false;
  26. return identical(T1.left, T2.left) && identical(T1.right, T2.right);
  27. }
  28. }

源码分析

这道题的异常处理相对 trick 一点,需要理解 null 对子树的含义。另外需要先调用identical再递归调用isSubtree判断左右子树的情况。方法identical中调用.val前需要判断是否为 null, 而后递归调用判断左右子树是否 identical。

复杂度分析

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

Reference