Count Total Nodes in Binary Tree in DSA Typescript - Time & Space Complexity
We want to understand how long it takes to count all nodes in a binary tree.
How does the time grow as the tree gets bigger?
Analyze the time complexity of the following code snippet.
function countNodes(root: TreeNode | null): number {
if (root === null) return 0;
return 1 + countNodes(root.left) + countNodes(root.right);
}
This code counts all nodes by visiting each node once in the binary tree.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive calls visiting each node once.
- How many times: Once per node in the tree.
Each node is visited once, so the work grows directly with the number of nodes.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 visits |
| 100 | About 100 visits |
| 1000 | About 1000 visits |
Pattern observation: The time grows linearly as the tree size increases.
Time Complexity: O(n)
This means the time to count nodes grows directly with the number of nodes in the tree.
[X] Wrong: "Counting nodes is faster because we only check the root or just one side."
[OK] Correct: Every node must be visited to count it, so skipping parts misses nodes and gives wrong results.
Counting nodes is a basic skill that shows you understand tree traversal and recursion, which are common in many problems.
"What if we used an iterative approach with a stack instead of recursion? How would the time complexity change?"
Practice
Solution
Step 1: Understand the base case for an empty tree
When the binary tree is empty, there are no nodes to count, so the count should be zero.Step 2: Confirm the function's return value for empty input
The function should return 0 to indicate no nodes exist in the tree.Final Answer:
0 -> Option CQuick Check:
Empty tree node count = 0 [OK]
- Returning 1 for empty tree
- Returning null instead of 0
- Confusing empty tree with leaf node
Solution
Step 1: Identify correct parameter type for binary tree root
The root should be a TreeNode or null if the tree is empty.Step 2: Confirm return type for count function
The function returns a number representing total nodes, so return type must be number.Final Answer:
function countNodes(root: TreeNode | null): number -> Option DQuick Check:
Correct parameter and return types = function countNodes(root: TreeNode | null): number [OK]
- Using wrong parameter type
- Returning void instead of number
- Returning string instead of number
console.log(countNodes(root));?
class TreeNode {
val: number;
left: TreeNode | null;
right: TreeNode | null;
constructor(val: number) {
this.val = val;
this.left = null;
this.right = null;
}
}
function countNodes(root: TreeNode | null): number {
if (!root) return 0;
return 1 + countNodes(root.left) + countNodes(root.right);
}
const root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
Solution
Step 1: Count nodes in the tree structure
The tree has nodes: 1 (root), 2 and 3 (children), 4 and 5 (children of 2). Total nodes = 5.Step 2: Verify recursive count function output
The function counts 1 for root plus counts of left and right subtrees, summing to 5.Final Answer:
5 -> Option AQuick Check:
Total nodes counted = 5 [OK]
- Counting only leaf nodes
- Missing one subtree
- Off-by-one error in count
function countNodes(root: TreeNode | null): number {
if (root === null) return 1;
return 1 + countNodes(root.left) + countNodes(root.right);
}Solution
Step 1: Check base case return value
The base case returns 1 when root is null, which incorrectly counts non-existent nodes.Step 2: Understand correct base case for counting nodes
For null nodes, the count should be 0, not 1, to avoid overcounting.Final Answer:
Base case returns 1 instead of 0 for null -> Option BQuick Check:
Base case must return 0 for null [OK]
- Returning 1 for null node
- Not counting current node
- Wrong parameter or return types
function countEvenNodes(root: TreeNode | null): number {
if (!root) return 0;
const leftCount = countEvenNodes(root.left);
const rightCount = countEvenNodes(root.right);
// What to add here?
}Solution
Step 1: Check node value for evenness
Use modulo operator to check if root.val is even; if yes, count 1, else 0.Step 2: Sum counts from left, right, and current node if even
Add leftCount, rightCount, and 1 or 0 based on current node's evenness.Final Answer:
return (root.val % 2 === 0 ? 1 : 0) + leftCount + rightCount; -> Option AQuick Check:
Count only even nodes correctly [OK]
- Counting all nodes regardless of value
- Counting odd nodes instead
- Forgetting to add left and right counts
Ready to prove it?
Pass the test and this pattern moves unknown
