二叉树 
      
    
      
      
      
        哈希表 
      
    
      
      
      
        广度优先搜索 
      
    
      
      
      
        树 
      
    
      
      
      
        深度优先搜索 
      
    
      
      
      
        设计 
      
    
   
  
    
      
       
  
  
    
      
    
    
      
       
  
题目描述 
给出一个满足下述规则的二叉树:
    root.val == 0对于任意 treeNode:
    
        如果 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, 104 ] 之间 
    调用 find() 的总次数在 [1, 104 ] 之间 
    0 <= target <= 106  
解法 
方法一:DFS + 哈希表 
我们先通过 DFS 遍历二叉树,将节点值恢复为原来的值,并将所有节点值存入哈希表中。然后在查找时,只需要判断哈希表中是否存在目标值即可。
时间复杂度方面,初始化时需要遍历二叉树,时间复杂度为 \(O(n)\) ,查找时只需要判断哈希表中是否存在目标值,时间复杂度为 \(O(1)\) 。空间复杂度 \(O(n)\) 。其中 \(n\)  为二叉树节点个数。
Python3 Java C++ Go TypeScript JavaScript 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 # Definition for a binary tree node. 
# class TreeNode: 
#     def __init__(self, val=0, left=None, right=None): 
#         self.val = val 
#         self.left = left 
#         self.right = right 
class   FindElements : 
    def   __init__ ( self ,  root :  Optional [ TreeNode ]): 
        def   dfs ( root :  Optional [ TreeNode ]): 
            self . s . add ( root . val ) 
            if  root . left : 
                root . left . val  =  root . val  *  2  +  1 
                dfs ( root . left ) 
            if  root . right : 
                root . right . val  =  root . val  *  2  +  2 
                dfs ( root . right ) 
        root . val  =  0 
        self . s  =  set () 
        dfs ( root ) 
    def   find ( self ,  target :  int )  ->  bool : 
        return  target  in  self . s 
# Your FindElements object will be instantiated and called as such: 
# obj = FindElements(root) 
# param_1 = obj.find(target) 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 /** 
 * Definition for a binary tree node. 
 * public class TreeNode { 
 *     int val; 
 *     TreeNode left; 
 *     TreeNode right; 
 *     TreeNode() {} 
 *     TreeNode(int val) { this.val = val; } 
 *     TreeNode(int val, TreeNode left, TreeNode right) { 
 *         this.val = val; 
 *         this.left = left; 
 *         this.right = right; 
 *     } 
 * } 
 */ 
class  FindElements   { 
     private   Set < Integer >   s   =   new   HashSet <> (); 
     public   FindElements ( TreeNode   root )   { 
         root . val   =   0 ; 
         dfs ( root ); 
     } 
     public   boolean   find ( int   target )   { 
         return   s . contains ( target ); 
     } 
     private   void   dfs ( TreeNode   root )   { 
         s . add ( root . val ); 
         if   ( root . left   !=   null )   { 
             root . left . val   =   root . val   *   2   +   1 ; 
             dfs ( root . left ); 
         } 
         if   ( root . right   !=   null )   { 
             root . right . val   =   root . val   *   2   +   2 ; 
             dfs ( root . right ); 
         } 
     } 
} 
/** 
 * Your FindElements object will be instantiated and called as such: 
 * FindElements obj = new FindElements(root); 
 * boolean param_1 = obj.find(target); 
 */ 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 /** 
 * Definition for a binary tree node. 
 * 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   { 
public : 
     FindElements ( TreeNode *   root )   { 
         root -> val   =   0 ; 
         dfs ( root ); 
     } 
     bool   find ( int   target )   { 
         return   s . contains ( target ); 
     } 
private : 
     unordered_set < int >   s ; 
     void   dfs ( TreeNode *   root )   { 
         s . insert ( root -> val ); 
         if   ( root -> left )   { 
             root -> left -> val   =   root -> val   *   2   +   1 ; 
             dfs ( root -> left ); 
         } 
         if   ( root -> right )   { 
             root -> right -> val   =   root -> val   *   2   +   2 ; 
             dfs ( root -> right ); 
         } 
     }; 
}; 
/** 
 * Your FindElements object will be instantiated and called as such: 
 * FindElements* obj = new FindElements(root); 
 * bool param_1 = obj->find(target); 
 */ 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 /** 
 * Definition for a binary tree node. 
 * type TreeNode struct { 
 *     Val int 
 *     Left *TreeNode 
 *     Right *TreeNode 
 * } 
 */ 
type   FindElements   struct   { 
     s   map [ int ] bool 
} 
func   Constructor ( root   * TreeNode )   FindElements   { 
     root . Val   =   0 
     s   :=   map [ int ] bool {} 
     var   dfs   func ( * TreeNode ) 
     dfs   =   func ( root   * TreeNode )   { 
         s [ root . Val ]   =   true 
         if   root . Left   !=   nil   { 
             root . Left . Val   =   root . Val * 2   +   1 
             dfs ( root . Left ) 
         } 
         if   root . Right   !=   nil   { 
             root . Right . Val   =   root . Val * 2   +   2 
             dfs ( root . Right ) 
         } 
     } 
     dfs ( root ) 
     return   FindElements { s } 
} 
func   ( this   * FindElements )   Find ( target   int )   bool   { 
     return   this . s [ target ] 
} 
/** 
 * Your FindElements object will be instantiated and called as such: 
 * obj := Constructor(root); 
 * param_1 := obj.Find(target); 
 */ 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 /** 
 * Definition for a binary tree node. 
 * class TreeNode { 
 *     val: number 
 *     left: TreeNode | null 
 *     right: TreeNode | null 
 *     constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { 
 *         this.val = (val===undefined ? 0 : val) 
 *         this.left = (left===undefined ? null : left) 
 *         this.right = (right===undefined ? null : right) 
 *     } 
 * } 
 */ 
class   FindElements   { 
     readonly   #s   =   new   Set < number > (); 
     constructor ( root :   TreeNode   |   null )   { 
         root . val   =   0 ; 
         const   dfs   =   ( node :   TreeNode   |   null ,   x   =   0 )   =>   { 
             if   ( ! node )   return ; 
             this . #s . add ( x ); 
             dfs ( node . left ,   x   *   2   +   1 ); 
             dfs ( node . right ,   x   *   2   +   2 ); 
         }; 
         dfs ( root ); 
     } 
     find ( target :   number ) :   boolean   { 
         return   this . #s . has ( target ); 
     } 
} 
/** 
 * Your FindElements object will be instantiated and called as such: 
 * var obj = new FindElements(root) 
 * var param_1 = obj.find(target) 
 */ 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 /** 
 * Definition for a binary tree node. 
 * function TreeNode(val, left, right) { 
 *     this.val = (val===undefined ? 0 : val) 
 *     this.left = (left===undefined ? null : left) 
 *     this.right = (right===undefined ? null : right) 
 * } 
 */ 
const   s   =   Symbol . for ( 's' ); 
/** 
 * @param {TreeNode} root 
 */ 
var   FindElements   =   function   ( root )   { 
     root . val   =   0 ; 
     this [ s ]   =   new   Set (); 
     const   dfs   =   ( node ,   x   =   0 )   =>   { 
         if   ( ! node )   return ; 
         this [ s ]. add ( x ); 
         dfs ( node . left ,   x   *   2   +   1 ); 
         dfs ( node . right ,   x   *   2   +   2 ); 
     }; 
     dfs ( root ); 
}; 
/** 
 * @param {number} target 
 * @return {boolean} 
 */ 
FindElements . prototype . find   =   function   ( target )   { 
     return   this [ s ]. has ( target ); 
}; 
/** 
 * Your FindElements object will be instantiated and called as such: 
 * var obj = new FindElements(root) 
 * var param_1 = obj.find(target) 
 */ 
 
 
    
    
    
    
      
  
    
      
  
     
  GitHub