🧠
Brute Force (Recursive Inorder Traversal)
💡 Recursion is the most natural way to traverse trees because trees are defined recursively. This approach helps beginners understand the traversal order and recursion stack before moving to iterative methods.
Intuition
Visit the left subtree recursively, then the current node, then the right subtree recursively. This directly follows the definition of inorder traversal.
Algorithm
- If the current node is null, return.
- Recursively traverse the left subtree.
- Visit the current node (add its value to the result).
- Recursively traverse the right subtree.
💡 The challenge is to remember the exact order of operations and how recursion implicitly uses a stack to remember nodes.
from typing import Optional, List
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def inorderTraversal(root: Optional[TreeNode]) -> List[int]:
result = []
def inorder(node):
if not node:
return
inorder(node.left) # traverse left subtree
result.append(node.val) # visit node
inorder(node.right) # traverse right subtree
inorder(root)
return result
# Driver code to test
if __name__ == '__main__':
# Construct tree: 1 -> right child 2 -> left child 3
root = TreeNode(1, None, TreeNode(2, TreeNode(3)))
print(inorderTraversal(root)) # Expected output: [1,3,2]
Line Notes
def inorder(node):Defines the recursive helper function to traverse nodes
if not node:Base case to stop recursion when reaching a leaf's child
inorder(node.left)Recursively traverse the left subtree first
result.append(node.val)Visit the current node by adding its value to the result list
inorder(node.right)Recursively traverse the right subtree after visiting current node
inorder(root)Start the recursion from the root node
return resultReturn the collected inorder traversal list
import java.util.*;
class TreeNode {
int val;
TreeNode left, right;
TreeNode(int val) { this.val = val; }
}
public class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
inorder(root, result);
return result;
}
private void inorder(TreeNode node, List<Integer> result) {
if (node == null) return;
inorder(node.left, result); // traverse left subtree
result.add(node.val); // visit node
inorder(node.right, result); // traverse right subtree
}
// Driver code
public static void main(String[] args) {
TreeNode root = new TreeNode(1);
root.right = new TreeNode(2);
root.right.left = new TreeNode(3);
Solution sol = new Solution();
System.out.println(sol.inorderTraversal(root)); // Expected: [1, 3, 2]
}
}
Line Notes
public List<Integer> inorderTraversal(TreeNode root)Public method to start inorder traversal and return result
if (node == null) return;Base case to stop recursion at leaf's child
inorder(node.left, result);Recursively traverse left subtree first
result.add(node.val);Visit current node by adding value to result list
inorder(node.right, result);Recursively traverse right subtree after visiting node
System.out.println(sol.inorderTraversal(root));Prints the inorder traversal result for verification
#include <iostream>
#include <vector>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution {
public:
void inorder(TreeNode* node, vector<int>& result) {
if (!node) return;
inorder(node->left, result); // traverse left subtree
result.push_back(node->val); // visit node
inorder(node->right, result); // traverse right subtree
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
inorder(root, result);
return result;
}
};
int main() {
TreeNode* root = new TreeNode(1);
root->right = new TreeNode(2);
root->right->left = new TreeNode(3);
Solution sol;
vector<int> res = sol.inorderTraversal(root);
for (int v : res) cout << v << ' '; // Expected output: 1 3 2
cout << endl;
return 0;
}
Line Notes
void inorder(TreeNode* node, vector<int>& result)Helper function to recursively traverse nodes
if (!node) return;Base case to stop recursion at null nodes
inorder(node->left, result);Traverse left subtree first recursively
result.push_back(node->val);Visit current node by adding value to result vector
inorder(node->right, result);Traverse right subtree recursively after visiting node
vector<int> inorderTraversal(TreeNode* root)Public method to initiate traversal and return result
for (int v : res) cout << v << ' ';Prints the traversal result for verification
function TreeNode(val, left = null, right = null) {
this.val = val;
this.left = left;
this.right = right;
}
function inorderTraversal(root) {
const result = [];
function inorder(node) {
if (!node) return;
inorder(node.left); // traverse left subtree
result.push(node.val); // visit node
inorder(node.right); // traverse right subtree
}
inorder(root);
return result;
}
// Driver code
const root = new TreeNode(1, null, new TreeNode(2, new TreeNode(3)));
console.log(inorderTraversal(root)); // Expected output: [1, 3, 2]
Line Notes
function inorder(node)Defines recursive helper function for traversal
if (!node) return;Stops recursion when node is null
inorder(node.left);Recursively traverse left subtree first
result.push(node.val);Visit current node by adding value to result array
inorder(node.right);Recursively traverse right subtree after visiting node
inorder(root);Start recursion from root node
return result;Return the collected inorder traversal array
Each node is visited exactly once. The recursion stack can go as deep as the height of the tree, which in worst case is O(n).
💡 For a tree with 20 nodes, this means about 20 function calls and 20 visits, which is efficient and easy to understand.
Interview Verdict: Accepted
This approach is accepted and commonly used in interviews to demonstrate understanding of recursion and tree traversal.