This is a fundamental and yet classic problem. I share my three solutions here:
- Iterative solution using stack ---
O(n)
time andO(n)
space; - Recursive solution ---
O(n)
time andO(n)
space (considering the spaces of call stack); - Morris traversal ---
O(n)
time andO(1)
space!!!
Iterative solution using stack:
1 vector<int> preorderTraversal(TreeNode* root) { 2 vector<int> nodes; 3 stack<TreeNode*> toVisit; 4 TreeNode* curNode = root; 5 while (curNode || !toVisit.empty()) { 6 if (curNode) { 7 nodes.push_back(curNode -> val); 8 if (curNode -> right) toVisit.push(curNode -> right); 9 curNode = curNode -> left; 10 } 11 else { 12 curNode = toVisit.top(); 13 toVisit.pop(); 14 } 15 } 16 return nodes; 17 }
Recursive soltuion:
1 void preorder(TreeNode* root, vector<int>& nodes) { 2 if (!root) return; 3 nodes.push_back(root -> val); 4 preorder(root -> left, nodes); 5 preorder(root -> right, nodes); 6 } 7 vector<int> preorderTraversal(TreeNode* root) { 8 vector<int> nodes; 9 preorder(root, nodes); 10 return nodes; 11 }
Morris traversal:
1 vector<int> preorderTraversal(TreeNode* root) { 2 TreeNode* curNode = root; 3 vector<int> nodes; 4 while (curNode) { 5 if (curNode -> left) { 6 TreeNode* predecessor = curNode -> left; 7 while (predecessor -> right && predecessor -> right != curNode) 8 predecessor = predecessor -> right; 9 if (!(predecessor -> right)) { 10 nodes.push_back(curNode -> val); 11 predecessor -> right = curNode; 12 curNode = curNode -> left; 13 } 14 else { 15 predecessor -> right = NULL; 16 curNode = curNode -> right; 17 } 18 } 19 else { 20 nodes.push_back(curNode -> val); 21 curNode = curNode -> right; 22 } 23 } 24 return nodes; 25 }