Reference: LeetCode
Difficulty: Medium
Problem
We are given the head node
rootof a binary tree, where additionally every node’s value is either a0or a1. Return the same tree where every subtree (of the given tree) not containing a1has been removed.
Recall that the subtree of a node
XisX, plus every node that is a descendant ofX.
Note:
- The binary tree will have at most 100 nodes.
- The value of each node will only be 0or1.
Example:
| 1 | Example 1: | 

| 1 | Example 2: | 

Analysis
Methods:
- Recursion- Prune children of the tree recursively. The only decision at each node is whether to prune the left child or the right child or not.
- containsOne(node): Whether the tree at this- nodecontains- 1, and it also prunes all subtrees not containing- 1, e.g.- node.leftdoes not contain a- 1, then we should prune it via- node.left = null.
- Also, the current node’s value needs to be checked.
- Time: $O(N)$
- Space: $O(h)$
 
Code
Recursion
Bad Code
Note:
- This is the first version I wrote, but it turns out that containsOne(node)does a lot of repeated jobs.
- To improve, consider the traversal order. We can put the line 1after visiting left subtree and right subtree. Therefore, traversal order sometimes is very important in performance or in reducing repeated calculations.
| 1 | public TreeNode pruneTree(TreeNode root) { | 
Change pruneTree to:
| 1 | return containsOne(root) ? root : null; | 
Change the line 1 & 2 to:
| 1 | boolean l = containsOne(root.left); // do it first! | 
I try using a HashMap to cache those calculated nodes, but the runtime does not improve and even get worse.
| 1 | public TreeNode pruneTree(TreeNode root) { | 
Clean Code
Note:
- Can we do pruning in containsOne(node)?
- It is a postordertraversal. Can we do it inpreorderway, which means checking the current node first? No! Ifroot.val == 1, we cannot just returntrue, since we need to check the children.
- If rootisnull, we should returnfalse. List all the base cases to see why it is the case.
| 1 | public TreeNode pruneTree(TreeNode root) { | 
