Binary Tree Pruning - Complete Solution Guide
Binary Tree Pruning is LeetCode problem 814, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
Given the root of a binary tree, return the same tree where every subtree (of the given tree) not containing a 1 has been removed . A subtree of a node node is node plus every node that is a descendant of node . Example 1: Input: root = [1,null,0,0,1] Output: [1,null,0,null,1] Explanation: Only the red nodes satisfy the property "every subtree not containing a 1". The diagram on the right represents the answer. Example 2: Input: root = [1,0,1,0,0,0,1] Output: [1,null,1,null,1] Example 3: Input:
Detailed Explanation
The problem asks us to prune a binary tree. Pruning means removing subtrees that don't contain the value '1'. A subtree is defined as a node and all its descendants. So, we need to traverse the tree and, for each node, check if the subtree rooted at that node contains at least one '1'. If it doesn't, we remove the entire subtree. The input is the root of the binary tree, and the output is the pruned tree.
Solution Approach
The solution uses a recursive post-order traversal of the binary tree. For each node, it first recursively calls the `pruneTree` function on the left and right subtrees. This ensures that the subtrees are pruned before the parent node is considered. After the recursive calls, the function checks if the current node's value is '0' and if both its left and right children are null (meaning they have been pruned or were initially null). If both conditions are true, the current node's subtree doesn't contain '1', so the function returns `null`, effectively pruning the node. Otherwise, it returns the current node, keeping it in the tree.
Step-by-Step Algorithm
- Step 1: Base Case: If the current node is null, return null. This handles empty trees and the bottom of the recursion.
- Step 2: Recursively prune the left subtree: `root.left = pruneTree(root.left)`.
- Step 3: Recursively prune the right subtree: `root.right = pruneTree(root.right)`.
- Step 4: Check if the current node should be pruned: If `root.val == 0` AND `root.left is None` AND `root.right is None`, return `None`.
- Step 5: Otherwise, return the current node: return `root`.
Key Insights
- Insight 1: A post-order traversal is essential. We need to process the left and right subtrees *before* deciding whether to prune the current node.
- Insight 2: Recursion simplifies the process. We can recursively prune the left and right subtrees, and then use the result to determine if the current node's subtree should be pruned.
- Insight 3: A node can be pruned if it has a value of '0' and its left and right children are null after pruning.
Complexity Analysis
Time Complexity: O(n)
Space Complexity: O(h)
Topics
This problem involves: Tree, Depth-First Search, Binary Tree.
Companies
Asked at: Hulu.