1261-在受污染的二叉树中查找元素

Raphael Liu Lv10

给出一个满足下述规则的二叉树:

  1. root.val == 0
  2. 如果 treeNode.val == xtreeNode.left != null,那么 treeNode.left.val == 2 * x + 1
  3. 如果 treeNode.val == xtreeNode.right != null,那么 treeNode.right.val == 2 * x + 2

现在这个二叉树受到「污染」,所有的 treeNode.val 都变成了 -1

请你先还原二叉树,然后实现 FindElements 类:

  • FindElements(TreeNode* root) 用受污染的二叉树初始化对象,你需要先把它还原。
  • bool find(int target) 判断目标值 target 是否存在于还原后的二叉树中并返回结果。

示例 1:

![](https://assets.leetcode-cn.com/aliyun-lc-
upload/uploads/2019/11/16/untitled-diagram-4-1.jpg)

**输入:**
["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:

![](https://assets.leetcode-cn.com/aliyun-lc-
upload/uploads/2019/11/16/untitled-diagram-4.jpg)

**输入:**
["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:

![](https://assets.leetcode-cn.com/aliyun-lc-
upload/uploads/2019/11/16/untitled-diagram-4-1-1.jpg)

**输入:**
["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

image.png

我做到了内存优于100%。但当我看到别人使用了Set时,其实我的内心是崩溃的。

我的find方法是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
         1
2 3
4 5 6 7
8 9 10 11 ...(放不下了就不写了,知道意思就好)

转换成二进制就是这样的

1
2
3
4
                1
10 11
100 101 110 111
1000 1001 ...

可以看到所有子节点和父节点都有相同的前缀,而当最后一位是0时则走左侧,是1时则走右侧。算法由此而得。

算法时间复杂度 O(logn),(n是参数target的值,底数为2),查找任何Integer数字,最多只需要循环32次。 空间复杂度 O(1),仅需要固定空间即可。

 Comments
On this page
1261-在受污染的二叉树中查找元素