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:
root.val == 0
- If
treeNode.val == x
andtreeNode.left != null
, thentreeNode.left.val == 2 * x + 1
- If
treeNode.val == x
andtreeNode.right != null
, thentreeNode.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)
Returntrue
if thetarget
value exists in the recovered binary tree.
Example 1:
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:
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:
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); */