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);
*/