Skip to main content

Recover a Tree From Preorder Traversal - Solution & Explanation

HardStringTreeDepth-First SearchBinary Tree11 min readAsked at: Amazon, Microsoft, Meta +3
Practice this problem

Problem Statement

We run a preorder depth-first search (DFS) on the root of a binary tree.

At each node in this traversal, we output D dashes (where D is the depth of this node), then we output the value of this node.  If the depth of a node is D, the depth of its immediate child is D + 1.  The depth of the root node is 0.

If a node has only one child, that child is guaranteed to be the left child.

Given the output traversal of this traversal, recover the tree and return its root.

 

Example 1:

Input: traversal = "1-2--3--4-5--6--7"
Output: [1,2,5,3,4,6,7]

Example 2:

Input: traversal = "1-2--3---4-5--6---7"
Output: [1,2,5,3,null,6,null,4,null,7]

Example 3:

Input: traversal = "1-401--349---90--88"
Output: [1,401,null,349,88,90]

 

Constraints:

  • The number of nodes in the original tree is in the range [1, 1000].
  • 1 <= Node.val <= 109

Approach Overview

Problem Overview: The input string represents a preorder traversal of a binary tree where node depth is encoded using dashes (-). Each node value appears after a sequence of dashes equal to its depth. Your task is to rebuild the original binary tree from this encoded preorder string.

Approach 1: Recursive Parsing with DFS (Time: O(n), Space: O(h))

This method parses the string while recursively building the tree in preorder order. First read the number of dashes to determine the node’s depth, then parse the integer value that follows. If the current depth matches the expected depth, create the node and recursively build its left and right children. If the dash count does not match the expected depth, backtrack so the parent call can attach the node correctly. The traversal naturally mirrors preorder construction using depth-first search. Time complexity is O(n) because each character in the string is processed once, and space complexity is O(h) due to the recursion stack where h is tree height.

Approach 2: Iterative Construction Using Stack (Time: O(n), Space: O(n))

The iterative approach processes the string left to right and uses a stack to track the path from root to the current node. First count dashes to determine the node depth, then parse the node value. While the stack size is greater than the current depth, pop nodes until the parent at depth d-1 remains on top. Attach the new node as the left child if empty, otherwise as the right child. Push the new node onto the stack to maintain the traversal path. The stack effectively represents the current root-to-node path in the tree. Each node is pushed and popped at most once, giving O(n) time and O(n) auxiliary space.

Recommended for interviews: The stack-based iterative approach is typically expected in interviews because it directly models the preorder traversal path and avoids complex recursion state management. The recursive solution demonstrates strong understanding of preorder parsing and DFS construction, but the stack version is easier to reason about under time pressure while maintaining the optimal O(n) runtime.

Approach 1: Recursive Approach

In this approach, we recursively parse the traversal string to construct the tree. We track the current position in the string and the expected depth using recursion. For each valid node, we create a new tree node and attempt to construct its left and right subtrees by increasing the expected depth.

The code defines a TreeNode class and a recoverFromPreorder function that constructs a binary tree from the given traversal string. This is done using a nested helper function that recursively builds the tree. The function uses a nonlocal index variable to maintain the current position within the string.

For each node, helper checks the number of dashes to see if they match the expected depth. If they match, it extracts the number representing the node's value, creates a TreeNode, and attempts to add left and right children by increasing the expected depth.

Code

Python

C++

Java

Complexity

Time Complexity: O(n), where n is the length of the traversal string, since each character is processed once.

Space Complexity: O(h), where h is the height of the tree, as this is the maximum depth of the recursion stack.

Try this approach in the editor β†’

Approach 2: Iterative Approach Using Stack

An iterative approach can be implemented using a stack. We use the stack to keep track of nodes along with their depths, and iteratively add nodes while maintaining the correct parent-child relationships. Each new node is inserted as a child of the node on the top of the stack, with adjustments made based on depths.

In Python, an iterative solution uses a stack to manage nodes and depths while parsing the traversal string. The number of dashes determines the depth. Nodes are created based on parsed values, and the stack is leveraged to attach each node at the correct position in the tree. Levels deeper than the current node's depth are popped from the stack, associating nodes as the left (and subsequently right) child of the last valid node at that depth.

Code

Python

C#

JavaScript

Complexity

Time Complexity: O(n), where n is the string length, as each character is evaluated once.

Space Complexity: O(h), where h is the height of the tree, related to the maximum size of the stack.

Try this approach in the editor β†’

Approach 3: Default Approach

Code

Java

C++

TypeScript

JavaScript

Try this approach in the editor β†’

Complexity Comparison

ApproachComplexity
Recursive Approach

Time Complexity: O(n), where n is the length of the traversal string, since each character is processed once.

Space Complexity: O(h), where h is the height of the tree, as this is the maximum depth of the recursion stack.

Iterative Approach Using Stack

Time Complexity: O(n), where n is the string length, as each character is evaluated once.

Space Complexity: O(h), where h is the height of the tree, related to the maximum size of the stack.

Default Approachβ€”

Detailed Complexity Analysis

ApproachTimeSpaceWhen to Use
Recursive DFS ParsingO(n)O(h)Good when recursion is comfortable and you want code that mirrors preorder traversal logic
Iterative Stack ConstructionO(n)O(n)Preferred in interviews; stack explicitly tracks node depth and parent relationships

Video Solution

Recover a Tree From Preorder Traversal - Leetcode 1028 - Python β€’ NeetCodeIO β€’ 11,186 views views

Watch 9 more video solutions β†’

Frequently Asked Questions

Is Recover a Tree From Preorder Traversal easy or hard?
Recover a Tree From Preorder Traversal is classified as a Hard problem because it combines string parsing with binary tree reconstruction. The challenge comes from correctly interpreting depth markers and maintaining parent-child relationships while preserving preorder structure.
Recover a Tree From Preorder Traversal Python/Java solution
Python, Java, and C++ solutions typically implement either recursive DFS parsing or an iterative stack approach. Both parse the traversal string to determine node depth and value, then connect nodes accordingly. The stack-based version is concise and widely used in Python and Java implementations.
How to solve Recover a Tree From Preorder Traversal in O(n)?
Parse the string sequentially while counting dashes to determine node depth and reading the numeric value that follows. Use a stack to track the current root-to-node path. Pop until the stack size matches the parent depth, attach the new node as a left or right child, and push it onto the stack. This processes every node once, achieving O(n) time.
What is the best approach for Recover a Tree From Preorder Traversal?
The stack-based iterative approach is generally the best choice. It scans the preorder string once, determines node depth from dash counts, and uses a stack to maintain the path from root to the current node. Each node is pushed and popped at most once, giving O(n) time complexity with O(n) auxiliary space.
Is Recover a Tree From Preorder Traversal asked at Google/Amazon/Meta?
Tree reconstruction and preorder parsing problems frequently appear in interviews at companies like Amazon, Google, and Meta. Variants that combine tree traversal with stack or DFS parsing are common because they test both string processing and binary tree construction skills.
What data structure is used in Recover a Tree From Preorder Traversal?
A stack is commonly used to track the path from the root to the current node during reconstruction. The algorithm also relies on binary tree node structures and preorder traversal properties. Some solutions instead use recursion with a DFS parsing strategy.
What is the time complexity of Recover a Tree From Preorder Traversal?
The optimal solutions run in O(n) time where n is the length of the traversal string. Each character is processed once to determine node depth and value. Stack operations or recursive calls also occur at most once per node, keeping the algorithm linear.

Ready to solve this problem?

Practice Recover a Tree From Preorder Traversal with our built-in code editor and test cases.

Practice on FleetCode