Description
144. Binary Tree Preorder Traversal
Given the root of a binary tree, return the preorder traversal of its nodes’ values.
Example 1:
Input: root = [1,null,2,3]
Output: [1,2,3]
Explanation:

Example 2:
Input: root = [1,2,3,4,5,null,8,null,null,6,7,9]
Output: [1,2,4,5,6,7,3,8,9]
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 .
Approach 1: Recursive Traversal ( Time, Space)
Intuition
Traverse the binary tree following the preorder sequence: Root node Left subtree Right subtree. Visit the current node by recording its value first, then recursively visit the left child, and finally the right child.
import java.util.ArrayList;
import java.util.List;
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
preorder(root, result);
return result;
}
private void preorder(TreeNode node, List<Integer> result) {
if (node == null) return;
result.add(node.val);
preorder(node.left, result);
preorder(node.right, result);
}
}
Complexity
- Time Complexity: — Visits every node in the binary tree exactly once.
- Space Complexity: worst-case call stack depth for a skewed tree ( for a balanced tree).
Approach 2: Iterative Stack (Unified Template — Time, Space)
Intuition
This approach uses the exact same structural template as iterative Inorder Traversal (curr pointer + inner/outer while loops with an explicit stack).
The only difference is when the node is visited:
- Preorder (Root Left Right): Record
curr.valon the way down inside the innerwhileloop right before pushingcurrto the stack and stepping left. - Once the left branch is exhausted, pop the node to backtrack and move to its right child (
curr = curr.right).
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Deque<TreeNode> stack = new ArrayDeque<>();
TreeNode curr = root;
while (curr != null || !stack.isEmpty()) {
// Traverse left branch and visit nodes on the way down
while (curr != null) {
result.add(curr.val); // Preorder: Visit root before moving left
stack.push(curr);
curr = curr.left;
}
// Backtrack to parent and step into the right subtree
curr = stack.pop();
curr = curr.right;
}
return result;
}
}
Complexity
- Time Complexity: — Each node in the tree is visited, pushed, and popped exactly once.
- Space Complexity: — Auxiliary space required for the explicit stack (
ArrayDeque), bounded by the height of the tree ( for a skewed tree, for a balanced tree).
Approach 3: Morris Preorder Traversal (Optimal — Time, Space)
Intuition
Achieve auxiliary space using temporary tree threading:
- If
curr.leftisnull, recordcurr.valand step right (curr = curr.right). - Otherwise, find the in-order predecessor (rightmost node in the left subtree):
- If
pred.rightisnull, recordcurr.valbefore traversing left, setpred.right = curr(temporary thread), and move left (curr = curr.left). - If
pred.right == curr, restore the tree structure by clearingpred.right = nulland move right (curr = curr.right).
- If
import java.util.ArrayList;
import java.util.List;
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
TreeNode curr = root;
while (curr != null) {
if (curr.left == null) {
result.add(curr.val);
curr = curr.right;
} else {
// Find in-order predecessor
TreeNode pred = curr.left;
while (pred.right != null && pred.right != curr) {
pred = pred.right;
}
if (pred.right == null) {
result.add(curr.val); // Visit root BEFORE creating thread and moving left
pred.right = curr; // Temporary thread back to curr
curr = curr.left;
} else {
pred.right = null; // Restore original tree structure
curr = curr.right;
}
}
}
return result;
}
}
Complexity
- Time Complexity: — Each edge is traversed at most twice.
- Space Complexity: auxiliary space — Modifies pointers in-place without recursion or extra data structures.
Easy Memory Rule
“Preorder pattern: Node Left Right. Push Right child then Left child onto stack so Left is visited first!”