Binary Tree Preorder Traversal
Given the root of a binary tree, return the preorder traversal of its node values: the node first, then its left subtree, then its right subtree.
Open on LeetCode ↗Intuition
Preorder visits a node the moment it's discovered — record first, explore later. It's the order you'd photocopy a tree: root, then everything under the left child, then everything under the right.
Node before children — the order in which you'd build a tree, which is why preorder plus inorder uniquely reconstructs one and why serialisation formats use it. The first element is always the root of the current subtree.
Approach
Visit before you descend
The only difference from inorder is where the append sits: record node.val before the two recursive calls. That single line move changes the output order completely — a good reminder that all three DFS traversals are the same walk, differing only in when they look at the node.
Why preorder matters
Because the root comes first, preorder is the natural order for copying or serializing a tree — you can rebuild the tree by reading the list left to right. It's also plain DFS order, the same sequence a stack-based explorer would discover nodes in.
Iterative version is the easiest of the three
Push root; loop: pop, visit, push right then left (right first so left pops first). No revisiting logic needed since the node is handled the moment it's popped.
Solution & live demo
Common pitfalls
Pushing children onto a stack left-first
stack.append(node.left) stack.append(node.right)
if node.right: stack.append(node.right) if node.left: stack.append(node.left)
In the iterative version a stack reverses insertion order, so pushing left first pops it second and the traversal mirrors. The right child must go on first for the left to be visited first.
Confusing it with level order
# BFS with a queue
res.append(node.val) dfs(node.left) dfs(node.right)
Preorder descends fully into the left subtree before touching the right; level order sweeps rank by rank. They agree on the root and diverge immediately after, which makes the mistake easy to miss on tiny test trees.
Appending inside the null check
if not node:
res.append(None)
returnif not node:
returnNull placeholders belong in serialisation, not in a traversal that reports values. Emitting them corrupts the output length and any index-based reconstruction downstream.
Edge cases
Base case returns immediately — empty list.
Each node is visited then recursion slides right; output equals the top-to-bottom chain.
Visited immediately; both child calls hit the base case.