You are given the root of a binary tree, return the preorder traversal of its nodes' values.
Example 1:
Input: root = [1,2,3,4,5,6,7]
Output: [1,2,4,5,3,6,7]Example 2:
Input: root = [1,2,3,null,4,5,null]
Output: [1,2,4,3,5]Example 3:
Input: root = []
Output: []Constraints:
0 <= number of nodes in the tree <= 100-100 <= Node.val <= 100Follow up: Recursive solution is trivial, could you do it iteratively?
Preorder traversal visits nodes in this exact order:
1. Node itself → 2. Left subtree → 3. Right subtree
So we simply start at the root and:
This naturally follows the preorder definition, and recursion handles the tree structure automatically.
res.node is null, return.res.res.# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
res = []
def preorder(node):
if not node:
return
res.append(node.val)
preorder(node.left)
preorder(node.right)
preorder(root)
return resPreorder traversal follows the pattern:
Visit Node → Left → Right
Using a stack, we can simulate recursion.
The trick:
This preserves the exact preorder sequence without recursion.
res for the result.cur = root.cur is not null or stack is not empty:cur exists:cur.val to res.cur.right onto the stack.cur to cur.left.cur to that node.res.# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
res = []
stack = []
cur = root
while cur or stack:
if cur:
res.append(cur.val)
stack.append(cur.right)
cur = cur.left
else:
cur = stack.pop()
return resMorris Traversal lets us do preorder traversal without recursion and without a stack, using O(1) extra space.
The key idea:
predecessor.right = currentThis modifies the tree temporarily but restores it fully at the end.
cur = root and an empty result list res.cur is not null:cur.left does NOT exist:cur (append value to res).cur.right.prev (rightmost node in cur.left).prev.right is null:cur.cur.val to res.prev.right = cur.cur.left.prev.right = None.cur.right.res.# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
res = []
cur = root
while cur:
if not cur.left:
res.append(cur.val)
cur = cur.right
else:
prev = cur.left
while prev.right and prev.right != cur:
prev = prev.right
if not prev.right:
res.append(cur.val)
prev.right = cur
cur = cur.left
else:
prev.right = None
cur = cur.right
return resPreorder requires visiting the current node before its children. Adding the value after recursive calls produces postorder traversal instead.
# Wrong: this is postorder, not preorder
preorder(node.left)
preorder(node.right)
res.append(node.val)In the iterative approach, the right child must be pushed onto the stack before the left child. Since stacks are LIFO, pushing left first causes right to be processed first.
# Wrong: processes right subtree before left
stack.append(cur.left) # should push right first
stack.append(cur.right)