Formatted question description: https://leetcode.ca/all/1261.html

1261. Find Elements in a Contaminated Binary Tree

Level

Medium

Description

Given a binary tree with the following rules:

  1. root.val == 0
  2. If treeNode.val == x and treeNode.left != null, then treeNode.left.val == 2 * x + 1
  3. If treeNode.val == x and treeNode.right != null, then treeNode.right.val == 2 * x + 2

Now the binary tree is contaminated, which means all treeNode.val have been changed to -1.

You need to first recover the binary tree and then implement the FindElements class:

  • FindElements(TreeNode* root) Initializes the object with a contamined binary tree, you need to recover it first.
  • bool find(int target) Return true if the target value exists in the recovered binary tree.

Example 1:

Image text

Input
["FindElements","find","find"]
[[[-1,null,-1]],[1],[2]]
Output
[null,false,true]
Explanation
FindElements findElements = new FindElements([-1,null,-1]); 
findElements.find(1); // return False 
findElements.find(2); // return True

Example 2:

Image text

Input
["FindElements","find","find","find"]
[[[-1,-1,-1,-1,-1]],[1],[3],[5]]
Output
[null,true,true,false]
Explanation
FindElements findElements = new FindElements([-1,-1,-1,-1,-1]);
findElements.find(1); // return True
findElements.find(3); // return True
findElements.find(5); // return False

Example 3:

Image text

Input
["FindElements","find","find","find","find"]
[[[-1,null,-1,-1,null,-1]],[2],[3],[4],[5]]
Output
[null,true,false,false,true]
Explanation
FindElements findElements = new FindElements([-1,null,-1,-1,null,-1]);
findElements.find(2); // return True
findElements.find(3); // return False
findElements.find(4); // return False
findElements.find(5); // return True

Constraints:

  • TreeNode.val == -1
  • The height of the binary tree is less than or equal to 20
  • The total number of nodes is between [1, 10^4]
  • Total calls of find() is between [1, 10^4]
  • 0 <= target <= 10^6

Solution

In the constructor, recover the tree using breadth first search. The root’s value is 0. For each node that is not a leaf, obtain its two children, and if a child is not null, recover the child’s value.

In the method boolean find(int target), first obtain the path from the root to the target, and then check whether there exists a node with value target. The path can be obtained using the relations between the parent’s value and its children’s values. To find the node, also use the relations.

  • /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class FindElements {
        TreeNode root;
    
        public FindElements(TreeNode root) {
            if (root != null) {
                breadthFirstSearch(root);
                this.root = root;
            }
        }
    
        public boolean find(int target) {
            if (root == null)
                return false;
            Stack<Integer> stack = new Stack<Integer>();
            int value = target;
            while (value > 0) {
                stack.push(value);
                value = (value - 1) / 2;
            }
            TreeNode node = root;
            while (node != null && !stack.isEmpty()) {
                int nextValue = stack.pop();
                if (nextValue == 2 * value + 1)
                    node = node.left;
                else if (nextValue == 2 * value + 2)
                    node = node.right;
                if (node != null && nextValue == target)
                    return true;
                else
                    value = nextValue;
            }
            return false;
        }
    
        private void breadthFirstSearch(TreeNode root) {
            root.val = 0;
            Queue<TreeNode> queue = new LinkedList<TreeNode>();
            queue.offer(root);
            while (!queue.isEmpty()) {
                TreeNode node = queue.poll();
                int val = node.val;
                TreeNode left = node.left, right = node.right;
                if (left != null) {
                    left.val = 2 * val + 1;
                    queue.offer(left);
                }
                if (right != null) {
                    right.val = 2 * val + 2;
                    queue.offer(right);
                }
            }
        }
    }
    
    /**
     * Your FindElements object will be instantiated and called as such:
     * FindElements obj = new FindElements(root);
     * boolean param_1 = obj.find(target);
     */
    
  • // OJ: https://leetcode.com/problems/find-elements-in-a-contaminated-binary-tree/
    // Time:
    //      FindElements: O(N)
    //      find: O(1)
    // Space: O(N)
    class FindElements {
        unordered_set<int> s;
        void recover(TreeNode *root, int val) {
            if (!root) return;
            root->val = val;
            s.insert(val);
            recover(root->left, 2 * val + 1);
            recover(root->right, 2 * val + 2);
        }
    public:
        FindElements(TreeNode* root) {
            recover(root, 0);
        }
        bool find(int target) {
            return s.count(target);
        }
    };
    
  • # 1261. Find Elements in a Contaminated Binary Tree
    # https://leetcode.com/problems/find-elements-in-a-contaminated-binary-tree/
    
    # Definition for a binary tree node.
    # class TreeNode:
    #     def __init__(self, val=0, left=None, right=None):
    #         self.val = val
    #         self.left = left
    #         self.right = right
    class FindElements:
    
        def __init__(self, root: TreeNode):
            root.val = 0
            self.s = set()
            self.build(root)
            
        def find(self, target: int) -> bool:
            return target in self.s
        
        def build(self, root):
            if not root: return
            
            if root.left:
                root.left.val = root.val*2 + 1
                self.s.add(root.left.val)
                self.build(root.left)
            
            if root.right:
                root.right.val = root.val*2 + 2
                self.s.add(root.right.val)
                self.build(root.right)
            
    
    
    # Your FindElements object will be instantiated and called as such:
    # obj = FindElements(root)
    # param_1 = obj.find(target)
    

All Problems

All Solutions