Welcome to Subscribe On Youtube

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);
     */
    
    ############
    
    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class FindElements {
        private Set<Integer> vis = new HashSet<>();
    
        public FindElements(TreeNode root) {
            root.val = 0;
            dfs(root);
        }
    
        private void dfs(TreeNode root) {
            vis.add(root.val);
            if (root.left != null) {
                root.left.val = root.val * 2 + 1;
                dfs(root.left);
            }
            if (root.right != null) {
                root.right.val = root.val * 2 + 2;
                dfs(root.right);
            }
        }
    
        public boolean find(int target) {
            return vis.contains(target);
        }
    }
    
    /**
     * 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);
        }
    };
    
  • # 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.nodes = {0}
    
            def dfs(root):
                if root is None:
                    return
                if root.left:
                    root.left.val = root.val * 2 + 1
                    self.nodes.add(root.left.val)
                if root.right:
                    root.right.val = root.val * 2 + 2
                    self.nodes.add(root.right.val)
                dfs(root.left)
                dfs(root.right)
    
            dfs(root)
    
        def find(self, target: int) -> bool:
            return target in self.nodes
    
    
    # Your FindElements object will be instantiated and called as such:
    # obj = FindElements(root)
    # param_1 = obj.find(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)
    
  • /**
     * Definition for a binary tree node.
     * type TreeNode struct {
     *     Val int
     *     Left *TreeNode
     *     Right *TreeNode
     * }
     */
    type FindElements struct {
    	vis map[int]bool
    }
    
    func Constructor(root *TreeNode) FindElements {
    	root.Val = 0
    	vis := map[int]bool{}
    	var dfs func(*TreeNode)
    	dfs = func(root *TreeNode) {
    		vis[root.Val] = true
    		if root.Left != nil {
    			root.Left.Val = root.Val*2 + 1
    			dfs(root.Left)
    		}
    		if root.Right != nil {
    			root.Right.Val = root.Val*2 + 2
    			dfs(root.Right)
    		}
    	}
    	dfs(root)
    	return FindElements{vis}
    }
    
    func (this *FindElements) Find(target int) bool {
    	return this.vis[target]
    }
    
    /**
     * Your FindElements object will be instantiated and called as such:
     * obj := Constructor(root);
     * param_1 := obj.Find(target);
     */
    

All Problems

All Solutions