Visit left subtree → process node → visit right subtree.
For BST: inorder gives sorted order.
example
// JavaScriptfunction inorder(root) {
const result = [];
function dfs(node) {
if (!node) return;
dfs(node.left);
result.push(node.val);
dfs(node.right);
}
dfs(root);
return result;
}
// Iterative with stackfunction inorderIterative(root) {
const result = [], stack = [];
let current = root;
while (current || stack.length) {
while (current) {
stack.push(current);
current = current.left;
}
current = stack.pop();
result.push(current.val);
current = current.right;
}
return result;
}
# Pythondef inorder(root):
result = []
def dfs(node):
ifnot node:
return
dfs(node.left)
result.append(node.val)
dfs(node.right)
dfs(root)
return result
output
Tree: 4
/ \
2 6
/ \
1 3
Inorder: [1, 2, 3, 4, 6]
Note Time O(n), Space O(h) where h = tree height. For balanced tree h = log n, for skewed h = n. Know both recursive and iterative versions — interviewers may ask for iterative. Inorder on BST is a common trick to verify sorted property.
Note Both O(n) time, O(h) space. Preorder is the order you would write nodes in serialization. Postorder is natural for bottom-up computations (e.g., calculating subtree sizes or heights). Interviewers may ask: given preorder + inorder, reconstruct the tree.
Note Time O(n), Space O(w) where w = max width of tree. Variants: zigzag level order (alternate direction), right side view (last node per level), average of levels. BFS is the natural tool whenever you need level-by-level information.
level orderBFS treebreadth first treetree by level
Maximum Depth of Binary Tree
syntax
Recursive: depth = 1 + max(depth(left), depth(right))
Base case: null node has depth 0.
Note Time O(n), Space O(h). One of the simplest tree recursion problems — great for warming up. Iterative BFS approach: count number of levels. Follow-up: minimum depth (BFS is more efficient — stops at first leaf).
max depthtree heightbinary tree depthrecursive depth
Validate Binary Search Tree
syntax
Pass down valid range (min, max) at each node.
Left child must be in (min, node.val).
Right child must be in (node.val, max).
example
// JavaScriptfunction isValidBST(root) {
function validate(node, min, max) {
if (!node) returntrue;
if (node.val <= min || node.val >= max) returnfalse;
return validate(node.left, min, node.val)
&& validate(node.right, node.val, max);
}
return validate(root, -Infinity, Infinity);
}
# Pythondef is_valid_bst(root):
def validate(node, lo, hi):
ifnot node:
returnTrueif node.val <= lo or node.val >= hi:
returnFalsereturn validate(node.left, lo, node.val) and \
validate(node.right, node.val, hi)
return validate(root, float('-inf'), float('inf'))
output
Valid BST: 5 Invalid: 5
/ \ / \
3 7 3 7
/ \ / \
1 4 1 6 ← 6 > 5 but in left subtree
Note Time O(n), Space O(h). Common mistake: only checking node against its parent. The range-based approach catches nodes that violate a grandparent constraint. Alternative: inorder traversal and verify the sequence is strictly increasing.
If current node is p or q, return it.
Recurse left and right.
If both sides return non-null, current node is the LCA.
Otherwise return whichever side is non-null.
example
// JavaScriptfunction lowestCommonAncestor(root, p, q) {
if (!root || root === p || root === q) return root;
const left = lowestCommonAncestor(root.left, p, q);
const right = lowestCommonAncestor(root.right, p, q);
if (left && right) return root;
return left || right;
}
# Pythondef lowest_common_ancestor(root, p, q):
ifnot root or root == p or root == q:
return root
left = lowest_common_ancestor(root.left, p, q)
right = lowest_common_ancestor(root.right, p, q)
if left and right:
return root
return left or right
Note Time O(n), Space O(h). For BST: exploit sorted property — if both values < node, go left; if both > node, go right; otherwise current node is LCA. This is an O(h) optimization for BSTs. Always clarify: can a node be its own ancestor?
lowest common ancestorLCAtree ancestorcommon parent
Path Sum
syntax
Subtract current node value from target as you recurse.
At a leaf, check if remaining target equals the leaf value.
example
// JavaScript — Has path with target sum (root to leaf)function hasPathSum(root, target) {
if (!root) returnfalse;
if (!root.left && !root.right) return root.val === target;
return hasPathSum(root.left, target - root.val)
|| hasPathSum(root.right, target - root.val);
}
# Pythondef has_path_sum(root, target):
ifnot root:
returnFalseifnot root.left andnot root.right:
return root.val == target
return has_path_sum(root.left, target - root.val) or \
has_path_sum(root.right, target - root.val)
Note Time O(n), Space O(h). Must reach a leaf — internal nodes with matching sum do not count. Variants: return all paths (collect paths in a list), path sum III (any downward path, use prefix sum + hash map). Clarify: root-to-leaf or any path?
path sumroot to leaftree pathtarget sum tree
Serialize & Deserialize Binary Tree (Concept)
syntax
Serialize: BFS or preorder DFS, use a marker fornull nodes.
Deserialize: reconstruct from the serialized format using same traversal order.
example
// JavaScript — Preorder approachfunction serialize(root) {
const parts = [];
function dfs(node) {
if (!node) { parts.push('X'); return; }
parts.push(String(node.val));
dfs(node.left);
dfs(node.right);
}
dfs(root);
return parts.join(',');
}
function deserialize(data) {
const vals = data.split(',');
let idx = 0;
function dfs() {
if (vals[idx] === 'X') { idx++; returnnull; }
const node = new TreeNode(Number(vals[idx++]));
node.left = dfs();
node.right = dfs();
return node;
}
return dfs();
}
# Pythondef serialize(root):
parts = []
def dfs(node):
ifnot node:
parts.append('X')
return
parts.append(str(node.val))
dfs(node.left)
dfs(node.right)
dfs(root)
return','.join(parts)
def deserialize(data):
vals = iter(data.split(','))
def dfs():
val = next(vals)
if val == 'X':
returnNone
node = TreeNode(int(val))
node.left = dfs()
node.right = dfs()
return node
return dfs()
Note Time O(n), Space O(n). The null marker is essential — without it you cannot reconstruct the tree uniquely. BFS approach works too: serialize level by level. This is a common hard interview question. Practice the deserialization — it is the tricky part.
serialize treedeserialize treeencode treetree to string