Find Elements in a Contaminated Binary Tree

medium tree design hash set bfs

Problem

You are given a binary tree whose every node value was overwritten with -1 (it is "contaminated"). The original tree followed a fixed rule: the root holds 0, and for any node holding x its left child holds 2x + 1 and its right child holds 2x + 2. First recover the original values, then build a structure that answers queries: does the recovered tree contain a given target value? Each call to find(target) returns true or false.

Inputtree = [-1, null, -1], find(1), find(2)
Output[false, true]
Recover: root → 0; it has only a right child → that child becomes 2·0 + 2 = 2. The recovered values are {0, 2}. So find(1) is false and find(2) is true.

class FindElements:
    def __init__(self, root):
        self.seen = set()
        def recover(node, val):
            if not node:
                return
            self.seen.add(val)
            recover(node.left, 2 * val + 1)
            recover(node.right, 2 * val + 2)
        recover(root, 0)

    def find(self, target):
        return target in self.seen
class FindElements {
  constructor(root) {
    this.seen = new Set();
    const recover = (node, val) => {
      if (!node) return;
      this.seen.add(val);
      recover(node.left, 2 * val + 1);
      recover(node.right, 2 * val + 2);
    };
    recover(root, 0);
  }
  find(target) {
    return this.seen.has(target);
  }
}
class FindElements {
    private Set<Integer> seen = new HashSet<>();
    public FindElements(TreeNode root) {
        recover(root, 0);
    }
    private void recover(TreeNode node, int val) {
        if (node == null) return;
        seen.add(val);
        recover(node.left, 2 * val + 1);
        recover(node.right, 2 * val + 2);
    }
    public boolean find(int target) {
        return seen.contains(target);
    }
}
class FindElements {
    unordered_set<int> seen;
    void recover(TreeNode* node, int val) {
        if (!node) return;
        seen.insert(val);
        recover(node->left, 2 * val + 1);
        recover(node->right, 2 * val + 2);
    }
public:
    FindElements(TreeNode* root) { recover(root, 0); }
    bool find(int target) {
        return seen.count(target) > 0;
    }
};
Time: O(n) build, O(1) per find Space: O(n)