Reference: LeetCode
Difficulty: Easy
My Post: [Java] Recursion (Node Comparison) & Preorder Sequence Comparison (StringBuilder)
Problem
Given two non-empty binary trees
sandt, check whether treethas exactly the same structure and node values with a subtree ofs. A subtree ofsis a tree consists of a node insand all of this node’s descendants. The treescould also be considered as a subtree of itself.
Example:
1 | // s t |
1 | // s t |
Analysis
Recursion (Node Comparison)
We can extract the recursive structure as follows:
isSubtree(s, t):
- The base case is:
- If
s == null && t == null, then returntrue. - If
s == null || t == null, then returnfalse.
- If
- If
isSame(s, t)istrue, then returntrue. - If
isSubtree(s.left, t)orisSubtree(s.right, t)istrue, then returntrue.
1 | public boolean isSubtree(TreeNode s, TreeNode t) { // takes O(m x n) |
Time: $O(m \times n)$
- $O(m)$: Every node in
sis traversed once. - $O(n)$: Do
isSame(s, t)for each node int, which traverses at most $n$ nodes int.
Space: $O(h_s)$ where $h_s$ is the height of s.
Preorder Sequence
We can find the preorder traversal of the tree s and t, and compare the preorder sequence. If the sequence $S_t$ is a substring of $S_s$, t is a subtree of s.
Also, in order to use this method, we need to treat children of leaf nodes as null value, and other values should have a prior # character to distinguish numbers such as 3 and 23.
Without StringBuilder (13 ms):
1 | public boolean isSubtree(TreeNode s, TreeNode t) { |
Use StringBuilder (5 ms):
1 | public boolean isSubtree(TreeNode s, TreeNode t) { |
Note:
- $m$ is the number of nodes in tree
s; $n$ is the number of nodes in treet. String concatenationtakes $O(k)$ for a k-length string. UsingStringBuilderreduces the time complexity to $O(1)$.
Time: Original: $O(m^2 + n^2 + m \times n)$; Use StringBuilder: $O(m + n)$
indexOftakes $O(m \times n)$, or $O(m + n)$ with KMP algorithm.
Space: $O(\max{(m, n)})$ because of strings.