Recover a Tree From Preorder Traversal

hard tree dfs stack string parsing

Problem

We run a preorder DFS on a binary tree and output each node as a number, prefixed by D dashes, where D is the node's depth (the root has depth 0). Given that string traversal, reconstruct and return the binary tree. If a node has only one child, it is guaranteed to be the left child.

Inputtraversal = "1-2--3--4-5--6--7"
Output[1, 2, 5, 3, 4, 6, 7]
Root 1 has children 2 (depth 1) and 5 (depth 1); node 2 has children 3 and 4 (depth 2); node 5 has children 6 and 7 (depth 2).

def recoverFromPreorder(traversal):
    stack = []
    i, n = 0, len(traversal)
    while i < n:
        depth = 0
        while i < n and traversal[i] == '-':
            depth += 1
            i += 1
        val = 0
        while i < n and traversal[i].isdigit():
            val = val * 10 + int(traversal[i])
            i += 1
        node = TreeNode(val)
        while len(stack) > depth:
            stack.pop()
        if stack:
            parent = stack[-1]
            if parent.left is None:
                parent.left = node
            else:
                parent.right = node
        stack.append(node)
    return stack[0]
function recoverFromPreorder(traversal) {
  const stack = [];
  let i = 0, n = traversal.length;
  while (i < n) {
    let depth = 0;
    while (i < n && traversal[i] === '-') { depth++; i++; }
    let val = 0;
    while (i < n && traversal[i] >= '0' && traversal[i] <= '9') {
      val = val * 10 + (traversal[i] - '0'); i++;
    }
    const node = { val, left: null, right: null };
    while (stack.length > depth) stack.pop();
    if (stack.length) {
      const parent = stack[stack.length - 1];
      if (parent.left === null) parent.left = node;
      else parent.right = node;
    }
    stack.push(node);
  }
  return stack[0];
}
class Solution {
    public TreeNode recoverFromPreorder(String traversal) {
        Deque<TreeNode> stack = new ArrayDeque<>();
        int i = 0, n = traversal.length();
        while (i < n) {
            int depth = 0;
            while (i < n && traversal.charAt(i) == '-') { depth++; i++; }
            int val = 0;
            while (i < n && Character.isDigit(traversal.charAt(i))) {
                val = val * 10 + (traversal.charAt(i) - '0'); i++;
            }
            TreeNode node = new TreeNode(val);
            while (stack.size() > depth) stack.pop();
            if (!stack.isEmpty()) {
                TreeNode parent = stack.peek();
                if (parent.left == null) parent.left = node;
                else parent.right = node;
            }
            stack.push(node);
        }
        TreeNode root = null;
        while (!stack.isEmpty()) root = stack.pop();
        return root;
    }
}
TreeNode* recoverFromPreorder(string traversal) {
    vector<TreeNode*> stack;
    int i = 0, n = traversal.size();
    while (i < n) {
        int depth = 0;
        while (i < n && traversal[i] == '-') { depth++; i++; }
        int val = 0;
        while (i < n && isdigit(traversal[i])) {
            val = val * 10 + (traversal[i] - '0'); i++;
        }
        TreeNode* node = new TreeNode(val);
        while ((int)stack.size() > depth) stack.pop_back();
        if (!stack.empty()) {
            TreeNode* parent = stack.back();
            if (parent->left == nullptr) parent->left = node;
            else parent->right = node;
        }
        stack.push_back(node);
    }
    return stack.front();
}
Time: O(n) Space: O(h)