← Home

94. Binary Tree Inorder Traversal

LeetCode article · C++ solution
Website made by wuisabel-gif · Original C++ code by keineahnung2345
two pointersC++Markdown
94

A good way into this one is to ask: what do we need to remember so we never redo work blindly? For 94. Binary Tree Inorder Traversal, the solution in this repository is mainly a two pointers solution.

Guide

What?

The code is easier to read if we treat it as a controlled search through possible states. Instead of trying to be clever immediately, read the code as a sequence of questions:

  • What state are we keeping?
  • How do we move from one state to the next?
  • When do we know the answer is already determined?

For this file, the main tools are: two pointers, stack, sliding window.

The notes already sitting in the source point us in the right direction:

  • Recursive

Guide

When?

Use this approach when the hard part is not syntax, but deciding what must stay true after every update. The accepted code reduces that pressure by storing exactly the information that remains useful later.

The important function names to track are inorderTraversalR, inorderTraversal.

Guide

Why?

The code is doing bookkeeping so your brain does not have to keep the entire search space open at once.

  • The stack stores unfinished context, which is usually the cleanest way to handle nested or monotonic structure.
  • The final return is not magic; it is the invariant after the loops or recursion have finished doing their accounting.

Guide

How?

Walk through the solution in this order:

  1. Read the setup variables first.
  2. Follow the main loop or recursive helper next.
  3. Watch where invalid states get skipped.
  4. Check which value survives to the return statement.

The most important competitive-programming habit here is to trust the invariant. Once the invariant is right, the loops become much less scary.

Guide

Complexity

  • Time: O(n) to O(n log n), depending on the dominant loop or data structure operation
  • Space: O(n) in the usual case for auxiliary containers or recursion

Guide

C++ Solution

Your submission

The accepted solution

solution.cpp
01//Recursive
02//Runtime: 4 ms, faster than 56.80% of C++ online submissions for Binary Tree Inorder Traversal.
03//Memory Usage: 9.3 MB, less than 77.00% of C++ online submissions for Binary Tree Inorder Traversal.
04/**
05 * Definition for a binary tree node.
06 * struct TreeNode {
07 *     int val;
08 *     TreeNode *left;
09 *     TreeNode *right;
10 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
11 * };
12 */
13class Solution {
14public:
15    vector<int> ans;
16    
17    void inorderTraversalR(TreeNode* root){
18        if(!root) return;
19        if(root->left){
20            inorderTraversal(root->left);
21        }
22        ans.push_back(root->val);
23        if(root->right){
24            inorderTraversal(root->right);
25        }
26    }
27    
28    vector<int> inorderTraversal(TreeNode* root) {
29        inorderTraversalR(root);
30        return ans;
31    }
32};
33
34//Runtime: 0 ms, faster than 100.00% of C++ online submissions for Binary Tree Inorder Traversal.
35//Memory Usage: 8 MB, less than 100.00% of C++ online submissions for Binary Tree Inorder Traversal.
36/**
37 * Definition for a binary tree node.
38 * struct TreeNode {
39 *     int val;
40 *     TreeNode *left;
41 *     TreeNode *right;
42 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
43 * };
44 */
45/**
46 * Definition for a binary tree node.
47 * struct TreeNode {
48 *     int val;
49 *     TreeNode *left;
50 *     TreeNode *right;
51 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
52 * };
53 */
54class Solution {
55public:
56    vector<int> inorderTraversal(TreeNode* root) {
57        stack<TreeNode*> stk;
58        TreeNode* cur = root;
59        vector<int> ans;
60        
61        stk.push(cur);
62        
63        do{
64            cur = stk.top();
65            
66            //go to its leftmost child
67            TreeNode* tmp = cur ? cur->left : NULL;
68            while(tmp){
69                stk.push(tmp);
70                tmp = tmp->left;
71            }
72            
73            //if it has left child, process leftmost child first
74            cur = stk.top(); stk.pop();
75            if(cur) ans.push_back(cur->val);
76            
77            //cut current node and its parent, 
78            //so current node won't be traversed again
79            if(stk.size() > 0) stk.top()->left = NULL;
80            
81            //deal with right child
82            if(cur && cur->right) stk.push(cur->right);
83        }while(!stk.empty());
84        
85        return ans;
86    }
87};
88
89//iterative, another version
90//Runtime: 4 ms, faster than 56.80% of C++ online submissions for Binary Tree Inorder Traversal.
91//Memory Usage: 8 MB, less than 100.00% of C++ online submissions for Binary Tree Inorder Traversal.
92/**
93 * Definition for a binary tree node.
94 * struct TreeNode {
95 *     int val;
96 *     TreeNode *left;
97 *     TreeNode *right;
98 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
99 * };
100 */
101class Solution {
102public:
103    vector<int> inorderTraversal(TreeNode* root) {
104        vector<int> ans;
105        stack<TreeNode*> stk;
106        TreeNode* cur;
107        
108        stk.push(root);
109        
110        while(!stk.empty()){
111            cur = stk.top();
112            while(cur && cur->left){
113                stk.push(cur->left);
114                cur = cur->left;
115            }
116            cur = stk.top(); stk.pop();
117            if(cur) ans.push_back(cur->val);
118            if(stk.size() > 0) stk.top()->left = nullptr;
119            if(cur && cur->right) stk.push(cur->right);
120        }
121        
122        return ans;
123    }
124};
125
126//Approach 2: Iterating method using Stack(official sol)
127//https://leetcode.com/problems/binary-tree-postorder-traversal/discuss/45551/Preorder-Inorder-and-Postorder-Iteratively-Summarization/188240
128//time: O(N), space: O(N)
129//Runtime: 0 ms, faster than 100.00% of C++ online submissions for Binary Tree Inorder Traversal.
130//Memory Usage: 8.5 MB, less than 100.00% of C++ online submissions for Binary Tree Inorder Traversal.
131/**
132 * Definition for a binary tree node.
133 * struct TreeNode {
134 *     int val;
135 *     TreeNode *left;
136 *     TreeNode *right;
137 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
138 * };
139 */
140class Solution {
141public:
142    vector<int> inorderTraversal(TreeNode* root) {
143        vector<int> ans;
144        stack<TreeNode*> stk;
145        TreeNode* cur = root;
146        while(cur || !stk.empty()){
147            //if cur is nullptr, it's ok, because it will later be stk.top()
148            while(cur){
149                stk.push(cur);
150                cur = cur->left;
151            }
152            cur = stk.top(); stk.pop();
153            ans.push_back(cur->val);
154            //it's fine if cur->right is nullptr
155            cur = cur->right;
156        }
157        
158        return ans;
159    }
160};
161
162//Approach 3: Morris Traversal
163//time: O(n), space: O(n)
164//Runtime: 4 ms, faster than 56.80% of C++ online submissions for Binary Tree Inorder Traversal.
165//Memory Usage: 8 MB, less than 100.00% of C++ online submissions for Binary Tree Inorder Traversal.
166/**
167 * Definition for a binary tree node.
168 * struct TreeNode {
169 *     int val;
170 *     TreeNode *left;
171 *     TreeNode *right;
172 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
173 * };
174 */
175class Solution {
176public:
177    vector<int> inorderTraversal(TreeNode* root) {
178        vector<int> ans;
179        TreeNode *cur = root, *pre;
180        
181        while(cur){
182            if(cur->left){
183                pre = cur->left;
184                while(pre->right){
185                    pre = pre->right;
186                }
187                //pre->right is now cur's rightmost child
188                //it doesn't have right child
189                //pre is the parent of cur's rightmost child
190                pre->right = cur;
191                TreeNode* tmp = cur;
192                //current root becomes its left child
193                cur = cur->left;
194                //cur original root's left subtree
195                tmp->left = nullptr;
196            }else{
197                ans.push_back(cur->val);
198                cur = cur->right;
199            }
200        }
201        
202        return ans;
203    }
204};

Cost

Complexity

Time
O(n) to O(n log n), depending on the dominant loop or data structure operation
Dominated by the main traversal, recursion, or data-structure operations in the code.
Space
O(n) in the usual case for auxiliary containers or recursion
Auxiliary state plus the answer structure where the problem requires one.