原文链接: https://leetcode-cn.com/problems/find-elements-in-a-contaminated-binary-tree
英文原文
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
.
Implement the FindElements
class:
FindElements(TreeNode* root)
Initializes the object with a contaminated binary tree and recovers it.bool find(int target)
Returnstrue
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, 104]
- Total calls of
find()
is between[1, 104]
0 <= target <= 106
中文题目
给出一个满足下述规则的二叉树:
root.val == 0
- 如果
treeNode.val == x
且treeNode.left != null
,那么treeNode.left.val == 2 * x + 1
- 如果
treeNode.val == x
且treeNode.right != null
,那么treeNode.right.val == 2 * x + 2
现在这个二叉树受到「污染」,所有的 treeNode.val
都变成了 -1
。
请你先还原二叉树,然后实现 FindElements
类:
FindElements(TreeNode* root)
用受污染的二叉树初始化对象,你需要先把它还原。bool find(int target)
判断目标值target
是否存在于还原后的二叉树中并返回结果。
示例 1:
输入: ["FindElements","find","find"] [[[-1,null,-1]],[1],[2]] 输出: [null,false,true] 解释: FindElements findElements = new FindElements([-1,null,-1]); findElements.find(1); // return False findElements.find(2); // return True
示例 2:
输入: ["FindElements","find","find","find"] [[[-1,-1,-1,-1,-1]],[1],[3],[5]] 输出: [null,true,true,false] 解释: FindElements findElements = new FindElements([-1,-1,-1,-1,-1]); findElements.find(1); // return True findElements.find(3); // return True findElements.find(5); // return False
示例 3:
输入: ["FindElements","find","find","find","find"] [[[-1,null,-1,-1,null,-1]],[2],[3],[4],[5]] 输出: [null,true,false,false,true] 解释: 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
提示:
TreeNode.val == -1
- 二叉树的高度不超过
20
- 节点的总数在
[1, 10^4]
之间 - 调用
find()
的总次数在[1, 10^4]
之间 0 <= target <= 10^6
通过代码
高赞题解
我做到了内存优于100%。但当我看到别人使用了Set时,其实我的内心是崩溃的。
我的find方法是这样的:
public boolean find(int target) {
if (target < 0) {
return false;
}
TreeNode node = rootNode;
target++; // 将target加1,用以表示转换树中的值
int bit = Integer.highestOneBit(target) >> 1; // 找到次高位开始计算
while (bit > 0 && node != null) {
if ((target & bit) == 0) {
node = node.left;
} else {
node = node.right;
}
bit >>= 1;
}
return node != null;
}
大致的想法是,首先将完全树中的值加1,得到的树就是下面这样的:
1
2 3
4 5 6 7
8 9 10 11 ...(放不下了就不写了,知道意思就好)
转换成二进制就是这样的
1
10 11
100 101 110 111
1000 1001 ...
可以看到所有子节点和父节点都有相同的前缀,而当最后一位是0时则走左侧,是1时则走右侧。算法由此而得。
算法时间复杂度 O(logn),(n是参数target的值,底数为2),查找任何Integer数字,最多只需要循环32次。 空间复杂度 O(1),仅需要固定空间即可。
统计信息
通过次数 | 提交次数 | AC比率 |
---|---|---|
8189 | 11234 | 72.9% |
提交历史
提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
---|