You are given the root of a binary tree, return the inorder traversal of its nodes' values.
Example 1:
Input: root = [1,2,3,4,5,6,7]
Output: [4,2,5,1,6,3,7]Example 2:
Input: root = [1,2,3,null,4,5,null]
Output: [2,4,1,5,3]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?
Before attempting this problem, you should be comfortable with:
Inorder traversal visits nodes in the order: left subtree, current node, right subtree. For a binary search tree, this produces values in sorted order. We can use recursion to naturally handle the traversal by first recursing on the left child, then processing the current node, and finally recursing on the right child.
null, return immediately (base case).# 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 inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
res = []
def inorder(node):
if not node:
return
inorder(node.left)
res.append(node.val)
inorder(node.right)
inorder(root)
return resWe can simulate the recursive call stack using an explicit stack. The key insight is that we need to go as far left as possible, then process the current node, and move to the right subtree. The stack helps us remember which nodes we still need to process after finishing the left subtrees.
null or the stack is not empty:null, push it onto the stack and move to its left child.# 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 inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
res = []
stack = []
cur = root
while cur or stack:
while cur:
stack.append(cur)
cur = cur.left
cur = stack.pop()
res.append(cur.val)
cur = cur.right
return resMorris Traversal achieves O(1) extra space by temporarily modifying the tree structure. The idea is to create a temporary link from the rightmost node of the left subtree back to the current node. This allows us to return to the current node after traversing the left subtree without using a stack. After processing, we remove the temporary link to restore the original tree.
null:null, set it to the current node (create a thread) and move to the left child.# 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 inorderTraversal(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:
prev.right = cur
cur = cur.left
else:
prev.right = None
res.append(cur.val)
cur = cur.right
return resInorder traversal requires visiting left, then current, then right. A common mistake is adding the current node's value before or after both recursive calls, which produces preorder or postorder results instead.
# Wrong: res.append(node.val) before inorder(node.left)
# Correct: inorder(node.left), then res.append(node.val)After popping and processing a node from the stack, you must move to its right child. Forgetting cur = cur.right causes an infinite loop since the same node keeps getting processed.