加载中...
1261-在受污染的二叉树中查找元素(Find Elements in a Contaminated Binary Tree)
发表于:2021-12-03 | 分类: 中等
字数统计: 1k | 阅读时长: 5分钟 | 阅读量:

原文链接: https://leetcode-cn.com/problems/find-elements-in-a-contaminated-binary-tree

英文原文

Given a binary tree with the following rules:

  1. root.val == 0
  2. If treeNode.val == x and treeNode.left != null, then treeNode.left.val == 2 * x + 1
  3. If treeNode.val == 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
  • 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

中文题目

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

  1. root.val == 0
  2. 如果 treeNode.val == x 且 treeNode.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:

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

通过代码

高赞题解

image.png

我做到了内存优于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%

提交历史

提交时间 提交结果 执行时间 内存消耗 语言
上一篇:
1260-二维网格迁移(Shift 2D Grid)
下一篇:
1262-可被三整除的最大和(Greatest Sum Divisible by Three)
本文目录
本文目录