二叉树_题目16:1261. 在受污染的二叉树中查找元素

109 阅读3分钟

题目16:1261. 在受污染的二叉树中查找元素

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

同类题目

前置知识

题目描述

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

  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:

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

思路分析

方法一:深度遍历+hash

先序遍历:对于每一个节点设置其左右子节点并将设置后的值加入到hash

hash 表使用unordered_set,unordered_set本质是使用hash散列的方式存储数据,是一种使用hash值作为key的容器,所以当有频繁的搜索、插入和移除拥有常数时间

unordered_set存储原理是声明一个有n个桶的数据结构,计算加入到unordered_set的新的值hash,然后计算hash%n后的值x,将新的值加入到桶x中。当桶x中已经有了元素,就直接链接在后边

程序代码

方法一

 //https://leetcode.cn/problems/find-elements-in-a-contaminated-binary-tree/description/
 // 1261. 在受污染的二叉树中查找元素
 ​
 #include<iostream>
 #include<vector>
 #include<unordered_set>
 using namespace std;
 struct TreeNode {
     int val;
     TreeNode *left;
     TreeNode *right;
     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 };
 ​
 ​
 class FindElements {
 private:
     unordered_set<int> valset;
 public:
     void travel(TreeNode *root)
     {
         // base case
         if(root == nullptr)
         {
             return;
         }
         if(root->left)
         {
             root->left->val = 2*root->val + 1;
             valset.insert(root->left->val);
         }
         if(root->right)
         {
             root->right->val = 2*root->val + 2;
             valset.insert(root->right->val);
         }
         travel(root->left);
         travel(root->right);
 ​
     }
     // 用受污染的二叉树初始化对象,你需要先把它还原。
     FindElements(TreeNode* root) {
         root->val = 0;
         valset.insert(root->val);
         travel(root);
     }
 ​
 ​
     // 判断目标值 target 是否存在于还原后的二叉树中并返回结果。
     bool find(int target) {
         return valset.count(target) > 0;
     }
 };

复杂度分析

时间复杂度:构造过程是 O(N),其中 n 是二叉树中的节点个数,每个节点都会遍历一次。find 过程是O(1)

空间复杂度:构造过程是O(logN) ,其中logN 为二叉树的高度。hash 表是O(N),哈希表占用的空间为N

更多相关知识:github.com/pingguo1987…