Given a binary tree with the following rules:
root.val == 0
treeNode
:
treeNode.val
has a value x
and treeNode.left != null
, then treeNode.left.val == 2 * x + 1
treeNode.val
has a value 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
.
Implement the FindElements
class:
FindElements(TreeNode* root)
Initializes the object with a contaminated binary tree and recovers it.bool find(int target)
Returns true
if the target
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
20
[1, 104]
find()
is between [1, 104]
0 <= target <= 106
This problem involves recovering a contaminated binary tree and efficiently checking for the existence of a target value. The tree follows specific rules for node values: the root has value 0, and for any node with value x
, its left child has value 2x + 1
and its right child has value 2x + 2
. All node values are initially set to -1.
The most efficient approach combines Depth-First Search (DFS) with a hash set (or similar data structure like a set in Python or Java).
Initialization (FindElements
constructor):
x
, its left child is assigned 2x + 1
, and its right child is assigned 2x + 2
.self.s
in Python, s
in Java/C++/Go/TypeScript). This hash set acts as an index for efficient lookup.Search (find
method):
target
value exists, we simply look up the target
in the hash set. This operation has a time complexity of O(1) on average due to the constant-time nature of hash table lookups.Time Complexity:
Space Complexity:
The provided code in Python, Java, C++, Go, and TypeScript all implement this approach. The core logic remains consistent: a DFS for reconstruction and a hash set for efficient searching. The specifics of hash set implementation vary slightly between languages. Each code snippet demonstrates this solution effectively.
While this approach is optimal in terms of time complexity, alternative approaches exist (but are less efficient):
find
operation in the worst case.The DFS with a hash set method is superior because of its efficient O(1) average-case search time after the initial O(N) initialization.