Depth of Binary Tree (leetcode 104)
104. Maximum Depth of Binary Tree
Given the
rootof a binary tree, return its maximum depth. A binary tree's maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
Example 1:
Input: root = [3,9,20,null,null,15,7]
Output: 3
class Solution {
public int maxDepth(TreeNode root) {
if(root==null){
return 0;
}
return (1+(Math.max(maxDepth(root.left),maxDepth(root.right))));
}
}class Solution:
def maxDepth(self, root):
if not root:
return 0
return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))| Type | Value |
|---|---|
| Time | O(n) |
| Space | O(n) |
- Approach: Recursively calculate depth of left and right subtrees.
- Dry run (root=[3,9,20,null,null,15,7]):
- Left depth = 1 + max(0,0) = 1
- Right depth = 1 + max(1,1) = 2
- Return max(1,2) = 2
Preorder Traversal (LeetCode 144)
144. Binary Tree Preorder Traversal
Given the
rootof a binary tree, print the preorder traversal of its nodes' values.
Example 1:
Input: root = [1,null,2,3]
Output: 1 2 3
public void preOrder(Node root) {
if (root == null) return;
System.out.print(root.data + " ");
preOrder(root.left);
preOrder(root.right);
}class Solution:
def preOrder(self, root):
if not root:
return
print(root.data, end=" ")
self.preOrder(root.left)
self.preOrder(root.right)| Type | Value |
|---|---|
| Time | O(n) |
| Space | O(n) |
- Approach: Visit Root → Traverse Left → Traverse Right
- Dry run (root=[1,null,2,3]):
- Visit root (1) → print 1
- Traverse left of 1 (null)
- Traverse right of 1 (node 2)
- Visit node 2 → print 2
- Traverse left of 2 (node 3)
- Visit node 3 → print 3
- Traverse left & right of 3 (both null)
- Traverse right of 2 (null)
- Output is 1 2 3
Inorder Traversal (leetcode 94)
94. Binary Tree Inorder Traversal
Given the
rootof a binary tree, print the inorder traversal of its nodes' values.
Example 1:
Input: root = [1,null,2,3]
Output: [1,3,2]
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List <Integer> A=new ArrayList<>();
inorder(root,A);
return A;
}
public static void inorder(TreeNode root,List<Integer> A){
if(root==null) return;
inorder(root.left,A);
A.add(root.val);
inorder(root.right,A);
}
}class Solution:
def inorderTraversal(self, root):
res = []
def inorder(node):
if not node: return
inorder(node.left)
res.append(node.val)
inorder(node.right)
inorder(root)
return res| Type | Value |
|---|---|
| Time | O(n) |
| Space | O(n) |
- Approach: Traverse Left → Visit Root → Traverse Right
- Dry run (root=[1,null,2,3]):
- Traverse left of 1 (null)
- Visit root (1) → print 1
- Traverse right of 1 (node 2)
- Traverse left of 2 (node 3)
- Traverse left of 3 (null)
- Visit node 3 → print 3
- Traverse right of 3 (null)
- Visit node 2 → print 2
- Traverse right of 2 (null)
- Traverse left of 2 (node 3)
- Output is 1 3 2
Postorder Traversal (LeetCode 145)
145. Binary Tree Postorder Traversal
Given the
rootof a binary tree, print the postorder traversal of its nodes' values.
Example 1:
Input: root = [1,null,2,3]
Output: 3 2 1
public void postOrder(Node root) {
if(root==null) return ;
postOrder(root.left);
postOrder(root.right);
System.out.print(root.data + " ");
}class Solution:
def postOrder(self, root):
if not root:
return
self.postOrder(root.left)
self.postOrder(root.right)
print(root.data, end=" ")| Type | Value |
|---|---|
| Time | O(n) |
| Space | O(n) |
- Approach: Traverse Left → Traverse Right → Visit Root
- Dry run (root=[1,null,2,3]):
- Traverse left of 1 (null)
- Traverse right of 1 (node 2)
- Traverse left of 2 (node 3)
- Traverse left & right of 3 (null)
- Visit node 3 → print 3
- Traverse right of 2 (null)
- Visit node 2 → print 2
- Traverse left of 2 (node 3)
- Visit root (1) → print 1
- Output is 3 2 1
Search in a Binary Search Tree (Leetcode 700)
700. Search in a Binary Search Tree
You are given the
rootof a binary search tree (BST) and an integerkey. Search for the node whose value equalskeyand returntrueif it exists, otherwisefalse.
Example 1:
Input: root = [4,2,7,1,3], key = 2
Output: true
public boolean search(Node root, int key) {
if (root == null) return false;
if (root.data == key) return true;
if (key < root.data)
return search(root.left, key);
else
return search(root.right, key);
}class Solution:
def searchBST(self, root, val):
if not root:
return None
if root.val == val:
return root
if val < root.val:
return self.searchBST(root.left, val)
else:
return self.searchBST(root.right, val)| Type | Value |
|---|---|
| Time | O(h) |
| Space | O(h) |
- Approach: Recursively search left or right subtree based on whether the key is smaller or greater than current node. Time and space bounds depend on tree height
h(worst caseO(n)). - Dry run (root=[4,2,7,1,3], key=2):
- root=4, key=2 < 4 → go left
- root=2, key==2 → return true
Validate Binary Search Tree (leetcode 98)
98. Validate Binary Search Tree
Given the
rootof a binary tree, determine if it is a valid binary search tree (BST).
A valid BST is defined as follows:
- The left subtree of a node contains only nodes with keys strictly less than the node's key.
- The right subtree of a node contains only nodes with keys strictly greater than the node's key.
- Both the left and right subtrees must also be binary search trees.

Input: root = [2,1,3]
Output: true

Input: root = [5,1,4,null,null,3,6]
Output: false
Explanation: The root node's value is 5 but its right child's value is 4.
class Solution {
public boolean isValidBST(TreeNode root) {
return validate(root, Long.MIN_VALUE, Long.MAX_VALUE);
}
public boolean validate(TreeNode node, long min, long max) {
if (node == null) return true;
if (node.val <= min || node.val >= max) {
return false;
}
return validate(node.left, min, node.val) &&
validate(node.right, node.val, max);
}
}class Solution:
def isValidBST(self, root):
def validate(node, low, high):
if not node:
return True
if not (low < node.val < high):
return False
return validate(node.left, low, node.val) and validate(node.right, node.val, high)
return validate(root, float('-inf'), float('inf'))| Metric | Value |
|---|---|
| Time | O(n) |
| Space | O(h) |
- Dry run (root=[2,1,3]):
- validate(2, -INF, INF) -> true. Left = validate(1, -INF, 2)
- validate(1, -INF, 2) -> true.
- Right = validate(3, 2, INF) -> true. Returns true.
Invert Binary Tree (leetcode 226)
Given the
rootof a binary tree, invert the tree, and return its root.
Example 1:

Input: root = [4,2,7,1,3,6,9]
Output: [4,7,2,9,6,3,1]
Example 2:

Input: root = [2,1,3]
Output: [2,3,1]
Example 3:
Input: root = []
Output: []
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
invertTree(root.left);
invertTree(root.right);
return root;
}
}class Solution:
def invertTree(self, root):
if not root:
return None
root.left, root.right = root.right, root.left
self.invertTree(root.left)
self.invertTree(root.right)
return root| Metric | Value |
|---|---|
| Time | O(n) |
| Space | O(h) |
- Dry run (root=[2,1,3]):
- invertTree(2): swap left(1) and right(3) -> left=3, right=1.
- recurse on new left(3) and right(1). Leaves return null. Result is [2,3,1].
Same Tree (leetcode 100)
Given the roots of two binary trees
pandq, write a function to check if they are the same or not.
Two binary trees are considered the same if they are structurally identical, and the nodes have the same value.
Example 1:

Input: p = [1,2,3], q = [1,2,3]
Output: true
Example 2:

Input: p = [1,2], q = [1,null,2]
Output: false
Example 3:

Input: p = [1,2,1], q = [1,1,2]
Output: false
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) return true;
if (p == null || q == null) return false;
if (p.val != q.val) return false;
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
}class Solution:
def isSameTree(self, p, q):
if not p and not q:
return True
if not p or not q:
return False
if p.val != q.val:
return False
return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)| Metric | Value |
|---|---|
| Time | O(n) |
| Space | O(h) |
- Dry run (p=[1,2], q=[1,null,2]):
- isSameTree(1,1) -> val matches. Left: isSameTree(2,null)
- (2,null) -> returns false. Final return false.
Subtree Of Another Tree (Leetcode 571)
Given the roots of two binary trees
rootandsubRoot, returntrueif there is a subtree ofrootwith the same structure and node values ofsubRootandfalseotherwise.
A subtree of a binary tree
treeis a tree that consists of a node intreeand all of this node's descendants. The treetreecould also be considered as a subtree of itself.
Example 1:

Input: root = [3,4,5,1,2], subRoot = [4,1,2]
Output: true
Example 2:

Input: root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
Output: false
class Solution {
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
if (root == null) return false;
if (sameTree(root, subRoot)) return true;
return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);
}
public boolean sameTree(TreeNode a, TreeNode b) {
if (a == null && b == null) return true;
if (a == null || b == null) return false;
if (a.val != b.val) return false;
return sameTree(a.left, b.left) && sameTree(a.right, b.right);
}
}class Solution:
def isSubtree(self, root, subRoot):
if not root:
return False
if self.isSameTree(root, subRoot):
return True
return self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)
def isSameTree(self, a, b):
if not a and not b:
return True
if not a or not b:
return False
if a.val != b.val:
return False
return self.isSameTree(a.left, b.left) and self.isSameTree(a.right, b.right)| Metric | Value |
|---|---|
| Time | O(m × n) |
| Space | O(h) |
- Dry run (root=[3,4,5,1,2], subRoot=[4,1,2]):
- isSubtree(3, 4): sameTree(3, 4) -> false.
- recurse left: isSubtree(4, 4) -> sameTree(4, 4) -> matches 4. Left: 1 matches 1, right: 2 matches 2 -> true.
- Returns true.
Binary Tree Level Order Traversal (LeetCode 102)
102. Binary Tree Level Order Traversal
Given the
rootof a binary tree, return the level order traversal of its nodes' values. (i.e., from left to right, level by level).
Example 1:

Input: root = [3,9,20,null,null,15,7]
Output: [[3],[9,20],[15,7]]
Example 2:
Input: root = [1]
Output: [[1]]
Example 3:
Input: root = []
Output: []
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null)
return res;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while (!q.isEmpty()) {
int size = q.size();
List<Integer> level = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode node = q.poll();
level.add(node.val);
if (node.left != null)
q.offer(node.left);
if (node.right != null)
q.offer(node.right);
}
res.add(level);
}
return res;
}
}from collections import deque
class Solution:
def levelOrder(self, root):
res = []
if not root:
return res
queue = deque([root])
while queue:
level_size = len(queue)
level = []
for _ in range(level_size):
node = queue.popleft()
level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(level)
return res| Type | Value |
|---|---|
| Time | O(n) |
| Space | O(n) |
- Approach: BFS using a queue. Process nodes level by level, adding children to the queue.
- Dry run (root=[3,9,20,null,null,15,7]):
- Queue: [3]. Level 1: [3]. Add 9, 20.
- Queue: [9,20]. Level 2: [9,20]. Add 15, 7.
- Queue: [15,7]. Level 3: [15,7].
- Result: [[3],[9,20],[15,7]]
Kth Smallest Element in a BST (LeetCode 230)
230. Kth Smallest Element in a BST
Given the
rootof a binary search tree, and an integerk, return thekthsmallest value (1-indexed) of all the values of the nodes in the tree.
Example 1:

Input: root = [3,1,4,null,2], k = 1
Output: 1
Example 2:

Input: root = [5,3,6,2,4,null,null,1], k = 3
Output: 3
class Solution {
int count = 0;
int result = 0;
public int kthSmallest(TreeNode root, int k) {
inorder(root, k);
return result;
}
private void inorder(TreeNode node, int k) {
if (node == null)
return;
inorder(node.left, k);
count++;
if (count == k) {
result = node.val;
return;
}
inorder(node.right, k);
}
}class Solution:
def kthSmallest(self, root, k):
self.count = 0
self.result = 0
def inorder(node):
if not node: return
inorder(node.left)
self.count += 1
if self.count == k:
self.result = node.val
return
inorder(node.right)
inorder(root)
return self.result| Type | Value |
|---|---|
| Time | O(n) |
| Space | O(h) |
- Approach: Inorder traversal of a BST yields values in sorted order. We traverse left, increment count, and when count matches
k, we record the result. - Dry run (root=[3,1,4,null,2], k=1):
- inorder(3). left: inorder(1). left: null.
- count++ -> 1.
- count==1 -> result=1. Return.
- Returns 1.
Convert Sorted Array to Binary Search Tree (LeetCode 108)
108. Convert Sorted Array to Binary Search Tree
Given an integer array nums where the elements are sorted in ascending order, convert it to a height-balanced binary search tree.
Example 1:
Input: nums = [-10,-3,0,5,9]
Output: [0,-3,9,-10,null,5]
Example 2:
Input: nums = [1,3]
Output: [3,1]
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return build(nums, 0, nums.length - 1);
}
private TreeNode build(int[] nums, int l, int r) {
if (l > r)
return null;
int mid = (l + r) / 2;
TreeNode root = new TreeNode(nums[mid]);
root.left = build(nums, l, mid - 1);
root.right = build(nums, mid + 1, r);
return root;
}
}class Solution:
def sortedArrayToBST(self, nums):
def build(l, r):
if l > r: return None
mid = (l + r) // 2
root = TreeNode(nums[mid])
root.left = build(l, mid - 1)
root.right = build(mid + 1, r)
return root
return build(0, len(nums) - 1)| Type | Value |
|---|---|
| Time | O(n) |
| Space | O(log n) |
- Approach: Divide and conquer. Select the middle element as the root and recursively build the left and right subtrees from the left and right halves of the array.
- Dry run (nums=[-10,-3,0,5,9]):
- mid=2, root=0. Left: build([-10,-3]). Right: build([5,9]).
- Left mid=0, root=-10. Right sub of -10 is -3.
- Right mid=0, root=5. Right sub of 5 is 9.
- Returns tree: [0,-10,5,null,-3,null,9].
Binary Tree Maximum Path Sum (LeetCode 124)
124. Binary Tree Maximum Path Sum
Solved
Hard
Topics
Companies
A path in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. A node can only appear in the sequence at most once. Note that the path does not need to pass through the root.
The path sum of a path is the sum of the node's values in the path.
Given the root of a binary tree, return the maximum path sum of any non-empty path.
Example 1:

Input: root = [1,2,3]
Output: 6
Explanation: The optimal path is 2 -> 1 -> 3 with a path sum of 2 + 1 + 3 = 6.
Example 2:

Input: root = [-10,9,20,null,null,15,7]
Output: 42
Explanation: The optimal path is 15 -> 20 -> 7 with a path sum of 15 + 20 + 7 = 42.
class Solution {
int maxSum = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
dfs(root);
return maxSum;
}
private int dfs(TreeNode node) {
if (node == null)
return 0;
int left = Math.max(0, dfs(node.left));
int right = Math.max(0, dfs(node.right));
maxSum = Math.max(maxSum, left + right + node.val);
return node.val + Math.max(left, right);
}
}
class Solution:
def maxPathSum(self, root):
self.max_sum = float('-inf')
def dfs(node):
if not node:
return 0
left = max(0, dfs(node.left))
right = max(0, dfs(node.right))
self.max_sum = max(self.max_sum, left + right + node.val)
return node.val + max(left, right)
dfs(root)
return self.max_sumGiven the root of a binary tree, return the length of the diameter of the tree.
The diameter of a binary tree is the length of the longest path between any two nodes in a tree. This path may or may not pass through the root.
The length of a path between two nodes is represented by the number of edges between them.
Example 1:

Input: root = [1,2,3,4,5]
Output: 3
Explanation: 3 is the length of the path [4,2,1,3] or [5,2,1,3].
Example 2:
Input: root = [1,2]
Output: 1
class Solution {
int max = 0;
public int diameterOfBinaryTree(TreeNode root) {
dfs(root);
return max;
}
int dfs(TreeNode node) {
if (node == null) return 0;
int left = dfs(node.left);
int right = dfs(node.right);
max = Math.max(max, left + right);
return 1 + Math.max(left, right);
}
}class Solution:
def diameterOfBinaryTree(self, root):
self.max_diam = 0
def dfs(node):
if not node:
return 0
left = dfs(node.left)
right = dfs(node.right)
self.max_diam = max(self.max_diam, left + right)
return 1 + max(left, right)
dfs(root)
return self.max_diam| Type | Value |
|---|---|
| Time | O(n) |
| Space | O(h) |
- Approach: DFS post-order. For each node, compute depth of left and right subtrees. Diameter through this node is
left + right. Update max diameter, and return max depth1 + max(left, right). - Dry run (root=[1,2]):
- dfs(2) -> left=0, right=0, max=0. returns 1.
- dfs(1) -> left=1, right=0. max=max(0, 1+0)=1. returns 2.
- Global max is 1.