Problem

Given the root of a binary tree, return the preorder traversal of its nodes’ values.

Examples

Example 1: Input: root = [1,null,2,3] Output: [1,2,3] Explanation:

Example 2: Input: root = [1,2,3,4,5,null,8,null,null,6,7,9] Output: [1,2,4,5,6,7,3,8,9] Explanation:

Example 3: Input: root = [] Output: []

Example 4: Input: root = [1] Output: [1]

Constraints:

  • The number of nodes in the tree is in the range [0, 100].
  • -100 <= Node.val <= 100

Follow up: Recursive solution is trivial, could you do it iteratively?

Solution

/**
 * 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) {}
 * };
 */

Recursion - O(n) time - O(n) space

class Solution {
public:
    vector<int> result;
    vector<int> preorderTraversal(TreeNode* root) {
	    if (!root) return vector<int>();
        result.push_back(root -> val);
        preorderTraversal(root -> left);
        preorderTraversal(root -> right);
        return result;
    }
};
class Solution {
private:
    void preorderTraversal(TreeNode* root, vector<int>& answer) {
        if (!root) {
            return;
        }
        answer.push_back(root->val);               // visit the root
        preorderTraversal(root->left, answer);     // traverse left subtree
        preorderTraversal(root->right, answer);    // traverse right subtree
    }
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> answer;
        preorderTraversal(root, answer);
        return answer;
    }
};

Stack - O(n) time - O(n) space

Let’s start from the root and then at each iteration pop the current node out of the stack and push its child nodes. In the implemented strategy we push nodes into the output list following the order Top->Bottom and Left->Right, which naturally reproduces preorder traversal.

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        if (root == nullptr) return vector<int>();
 
        vector<TreeNode*> stack = {root};
        vector<int> output;
 
        while (!stack.empty()) {
            root = stack.back();
            stack.pop_back();
            if (root != nullptr) {
                output.push_back(root->val);
                if (root->right != nullptr) {
                    stack.push_back(root->right);
                }
                if (root->left != nullptr) {
                    stack.push_back(root->left);
                }
            }
        }
        return output;
    }
};

Morris Traversal - O(n) time - O(n) space

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        if (root == nullptr) {
            return vector<int>();
        }
 
        vector<TreeNode*> stack = {root};
        vector<int> output;
 
        while (!stack.empty()) {
            root = stack.back();
            stack.pop_back();
            if (root != nullptr) {
                output.push_back(root->val);
                if (root->right != nullptr) {
                    stack.push_back(root->right);
                }
                if (root->left != nullptr) {
                    stack.push_back(root->left);
                }
            }
        }
 
        return output;
    }
};