Your Success, Our Mission!
6000+ Careers Transformed.
This is it. You've mastered the theory, implementation, and real-world applications. Now it's time to put your knowledge to the test and think like a software engineer. This module is dedicated to solving classic tree coding interview questions.
For each problem, we will follow a structured approach:
Try to solve each problem on your own before looking at the solution. This practice is the single most effective way to prepare for interviews. Let's begin!
The Problem: Given the root of a binary tree, write a function to find its height. The height is the number of edges on the longest path from the root node down to a leaf node.
The Logic: This is a classic problem solved elegantly with recursion.
The Code:
public int findHeight(TreeNode root) {
// Base Case: An empty tree has a height of -1
if (root == null) {
return -1;
}
// Recursively find the height of the left and right subtrees
int leftHeight = findHeight(root.left);
int rightHeight = findHeight(root.right);
// The height of the tree is 1 + the max of the two subtrees
return 1 + Math.max(leftHeight, rightHeight);
}
Complexity: Time is O(n) as we must visit every node. Space is O(h) (height of the tree) for the recursion stack.
The Problem: Given the roots of two binary trees, p and q, write a function to check if they are structurally identical and have the same node values.
The Logic: We can solve this by traversing both trees simultaneously.
The Code:
public boolean isSameTree(TreeNode p, TreeNode q) {
// If both are null, they are identical
if (p == null && q == null) {
return true;
}
// If one is null or their values are different, they are not identical
if (p == null || q == null || p.data != q.data) {
return false;
}
// Recursively check the left and right subtrees
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
Complexity: Time is O(n) (where n is the number of nodes in the smaller tree). Space is O(h).
The Problem: This is a common interview variation of BFS. Given the root of a binary tree, return its nodes' values grouped by level, as a list of lists.
Example: For the tree in our previous modules, the output should be [[8], [3, 10], [1, 6, 14]].
The Logic: We use a standard BFS with a queue. The trick is to know how many nodes are in the current level so we can group them.
The Code:
import java.util.*;
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) {
return result;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
int levelSize = queue.size();
List<Integer> currentLevel = new ArrayList<>();
for (int i = 0; i < levelSize; i++) {
TreeNode currentNode = queue.poll();
currentLevel.add(currentNode.data);
if (currentNode.left != null) {
queue.add(currentNode.left);
}
if (currentNode.right != null) {
queue.add(currentNode.right);
}
}
result.add(currentLevel);
}
return result;
}
Complexity: Time is O(n). Space is O(w), where w is the maximum width of the tree.
The Problem: Given a Binary Search Tree (BST) and two nodes p and q, find their lowest common ancestor. The LCA is the lowest (deepest) node that has both p and q as descendants.
The Logic: We can leverage the BST property for a highly efficient solution.
The Code (Iterative):
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
TreeNode current = root;
while (current != null) {
if (p.data > current.data && q.data > current.data) {
// Both are in the right subtree
current = current.right;
} else if (p.data < current.data && q.data < current.data) {
// Both are in the left subtree
current = current.left;
} else {
// We found the split point, this is the LCA
return current;
}
}
return null; // Should not happen in a valid BST with existing nodes
}
Complexity: Time is O(h) (O(log n) on a balanced BST). Space is O(1) for the iterative solution.
Top Tutorials
Related Articles
All Courses (6)
Master's Degree (2)
Fellowship (2)
Certifications (2)