# 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):
result = []
stack = []
current = root
while current or stack:
while current:
stack.append(current)
current = current.left
current = stack.pop()
result.append(current.val)
current = current.right
return result
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> stk;
TreeNode* current = root;
while (current || !stk.empty()) {
while (current) {
stk.push(current);
current = current->left;
}
current = stk.top();
stk.pop();
result.push_back(current->val);
current = current->right;
}
return result;
}
};
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
import java.util.*;
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode current = root;
while (current != null || !stack.isEmpty()) {
while (current != null) {
stack.push(current);
current = current.left;
}
current = stack.pop();
result.add(current.val);
current = current.right;
}
return result;
}
}
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var inorderTraversal = function(root) {
const result = [];
const stack = [];
let current = root;
while (current || stack.length) {
while (current) {
stack.push(current);
current = current.left;
}
current = stack.pop();
result.push(current.val);
current = current.right;
}
return result;
};
Given the root
of a binary tree, return the inorder traversal of its nodes' values as a list. In an inorder traversal, you visit the left subtree first, then the root node, and finally the right subtree. The binary tree can have any structure (not necessarily a binary search tree).
To solve this problem, we first need to understand what an inorder traversal is. In a binary tree, inorder traversal means visiting the left subtree, then the current node, and finally the right subtree. The simplest way to do this is using recursion, but for interview settings, it's also important to know how to do it iteratively (without recursion), which uses a stack.
A brute-force approach would be to use recursion, which is straightforward but relies on the call stack. However, to avoid potential stack overflow with deep trees or to demonstrate iterative control, we can use an explicit stack. This transition from recursion to iteration is a key optimization and a common interview expectation.
The main challenge is managing the traversal order and making sure we visit each node exactly once, in the correct sequence.
We will use an iterative approach with an explicit stack to simulate the recursive call stack. Here’s how the algorithm works, step by step:
current
starting at the root node.current
is not null or the stack is not empty:
current
to the right child of the popped node and repeat the process.current
is null.This approach ensures that each node is processed in the correct order without recursion, and every node is visited exactly once.
Consider the following binary tree:
1 \ 2 / 3
The inorder traversal should return [1, 3, 2]
. Here’s how the algorithm works step by step:
[1, 3, 2]
.O(n)
, where n
is the number of nodes in the tree, since each node is visited once.O(h)
, where h
is the height of the tree, due to the call stack.
O(n)
, for the same reason—each node is visited exactly once.O(h)
, since the stack holds at most h
nodes at any time (the path from root to the current node).
Both approaches are optimal for this problem. The iterative approach avoids potential stack overflow with deep trees.
Inorder traversal is a fundamental tree operation. The iterative solution uses a stack to simulate recursion, ensuring each node is visited in the correct order. This approach is efficient, avoids recursion limits, and is easy to implement. The key insight is to process nodes by always traversing left first, then visiting the node, then traversing right—using a stack to remember where we are in the tree.