Leetcode 1028. Recover a Tree From Preorder Traversal

Problem Explanation:

In this problem, we are given a string representing a preorder depth-first search traversal of a binary tree where each node's value is preceded by - repeated by the depth of the node. Our task is to recover the original binary tree from this string. It is noted that if a node has only one child, the child is guaranteed to be the left child.

For example, given the input "1-2--3---4-5--6---7", the function should return a binary tree whose root node has value 1, and has left child 2 which itself has left child 3 and right child 5, 3 has left child 4 and 5 has left child 6 which itself has left child 7.

To approach this problem, we will traverse the given string and create the corresponding nodes in the tree. We will maintain an integer variable i, to mark our current position in the input string. Another variable, depth, will be used to control the depth of the tree nodes.

We will start by reading a number from the string until we encounter '-' and create a new node with that value. Then we create its left child by calling the function recursively and add 1 to the depth. Once we have created the left child, we create the right child following the same process.

Python Solution:

1
2python
3class Solution:
4    def recoverFromPreorder(self, S: str) -> TreeNode:
5        i, n = 0, len(S)
6        def recover(depth):
7            nonlocal i
8            if i == n or S[i] != '-':
9                return None
10            
11            i += depth
12            start = i
13            while i < n and S[i] != '-':
14                i += 1
15
16            node = TreeNode(S[start:i])
17            node.left = recover(depth+1)
18            node.right = recover(depth+1)
19            return node
20
21        return recover(0)

Java Solution:

1
2java
3class Solution {
4    int i = 0;
5    public TreeNode recoverFromPreorder(String S) {
6        return recoverFromPreorder(S, 0);
7    }
8
9    private TreeNode recoverFromPreorder(String S, int depth) {
10        int nDashes = 0;
11        while (i + nDashes < S.length() && S.charAt(i + nDashes) == '-')
12          ++nDashes;
13        if (nDashes != depth)
14          return null;
15
16        i += depth;
17        int start = i;
18        while (i < S.length() && Character.isDigit(S.charAt(i)))
19          ++i;
20
21        return new TreeNode(Integer.parseInt(S.substring(start, i)),
22                            recoverFromPreorder(S, depth + 1),
23                            recoverFromPreorder(S, depth + 1));
24    }
25}

JavaScript Solution:

1
2javascript
3class TreeNode {
4    constructor(val, left = null, right = null) {
5        this.val = val;
6        this.left = left;
7        this.right = right;
8    }
9}
10
11const recoverFromPreorder = (S) => {
12    var i = 0, n = S.length, recover = (depth) => {
13        var start = i;
14        if (i >= n || S[i] != "-") {
15            return null;
16        }
17        i += depth;
18        while (i < n && S[i] !== "-") {
19            i++;
20        }
21        var node = new TreeNode(parseInt(S.slice(start, i)))
22        node.left = recover(depth + 1);
23        node.right = recover(depth + 1);
24        return node;
25    }
26
27    return recover(0);
28}

As you can see from all the solutions, the pattern is identical. We recurse and increase the depth by 1 each time when we move to the next left or right child. This problem is basically a depth-first search problem where we recreate the binary tree node by node, and as we move from left child to right child, we increase our depth.

The Python solution uses the built-in TreeNode class from the Leetcode platform while in the JavaScript and Java solutions we create our own TreeNode classes.

This is a great example of how the recursion and depth-first search can be combined to solve complex data structure problems. A good understanding of binary trees and traversal methods is needed to easily grasp the problem's logic. By translating the logic into Python, JavaScript, and Java, we are able to see the common algorithm patterns across these different programming languages.


Got a question? Ask the Teaching Assistant anything you don't understand.

Still not clear? Ask in the Forum,  Discord or Submit the part you don't understand to our editors.


TA 👨‍🏫