Binary Tree Inorder Traversal
LeetCode 94 | Difficulty: Easyβ
EasyProblem Descriptionβ
Given the root of a binary tree, return the inorder traversal of its nodes' values.
Example 1:
Input: root = [1,null,2,3]
Output: [1,3,2]
Explanation:

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

Example 3:
Input: root = []
Output: []
Example 4:
Input: root = [1]
Output: [1]
Constraints:
- The number of nodes in the tree is in the range `[0, 100]`.
- `-100 <= Node.val <= 100`
Follow up: Recursive solution is trivial, could you do it iteratively?
Topics: Stack, Tree, Depth-First Search, Binary Tree
Approachβ
Tree DFSβ
Traverse the tree recursively (or with a stack). At each node, decide: what information do I need from the left/right subtrees? Process: go left β go right β combine results. Consider preorder, inorder, or postorder traversal based on when you need to process the node.
Path problems, subtree properties, tree structure manipulation.
Stackβ
Use a stack (LIFO) to track elements that need future processing. Process elements when a "trigger" condition is met (e.g., finding a smaller/larger element). Monotonic stack maintains elements in sorted order for next greater/smaller element problems.
Matching brackets, next greater element, evaluating expressions, backtracking history.
Solutionsβ
Solution 1: C# (Best: 173 ms)β
| Metric | Value |
|---|---|
| Runtime | 173 ms |
| Memory | 39.1 MB |
| Date | 2021-12-08 |
/**
* Definition for a binary tree node.
* public class TreeNode {
* public int val;
* public TreeNode left;
* public TreeNode right;
* public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
public class Solution {
public IList<int> InorderTraversal(TreeNode root) {
List<int> result = new List<int>();
TreeNode current = root, prev = null;
while(current != null)
{
if(current.left == null)
{
result.Add(current.val);
current = current.right;
}
else
{
// find predecessor
prev = current.left;
while(prev.right != null && prev.right != current)
{
prev = prev.right;
}
if(prev.right == null)
{
prev.right = current;
current = current.left;
}
else
{
prev.right = null;
result.Add(current.val);
current = current.right;
}
}
}
return result;
}
}
π 3 more C# submission(s)
Submission (2019-12-31) β 240 ms, 29.3 MBβ
/**
* Definition for a binary tree node.
* public class TreeNode {
* public int val;
* public TreeNode left;
* public TreeNode right;
* public TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public IList<int> InorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<TreeNode>();
List<int> inorder = new List<int>();
var current = root;
if(root==null) return inorder;
while(stack.Count!=0 || current != null )
{
while(current != null)
{
stack.Push(current);
current = current.left;
}
var popped = stack.Pop();
inorder.Add(popped.val);
current = popped.right;
}
return inorder;
}
}
Submission (2018-05-02) β 280 ms, N/Aβ
/**
* Definition for a binary tree node.
* public class TreeNode {
* public int val;
* public TreeNode left;
* public TreeNode right;
* public TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public IList<int> InorderTraversal(TreeNode root) {
System.Collections.Generic.Stack<TreeNode> stack = new Stack<TreeNode>();
List<int> inorder = new List<int>();
var current = root;
if(root==null) return inorder;
while(stack.Count!=0 || current != null )
{
if(current != null)
{
stack.Push(current);
current = current.left;
}
else
{
if(stack.Count!=0)
{
var popped = stack.Pop();
inorder.Add(popped.val);
current = popped.right;
}
}
}
return inorder;
}
}
Submission (2018-01-11) β 601 ms, N/Aβ
/**
* Definition for a binary tree node.
* public class TreeNode {
* public int val;
* public TreeNode left;
* public TreeNode right;
* public TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public IList<int> InorderTraversal(TreeNode root) {
System.Collections.Generic.Stack<TreeNode> stack = new Stack<TreeNode>();
List<int> inorder = new List<int>();
var current = root;
while(stack.Count!=0 || current != null )
{
if(current != null)
{
stack.Push(current);
current = current.left;
}
else
{
if(stack.Count!=0)
{
var popped = stack.Pop();
inorder.Add(popped.val);
current = popped.right;
}
}
}
return inorder;
}
}
Complexity Analysisβ
| Approach | Time | Space |
|---|---|---|
| Tree Traversal | $O(n)$ | $O(h)$ |
| Stack | $O(n)$ | $O(n)$ |
Interview Tipsβ
- Start by clarifying edge cases: empty input, single element, all duplicates.
- Consider: "What information do I need from each subtree?" β this defines your recursive return value.
- Think about what triggers a pop: is it finding a match, or finding a smaller/larger element?