[Java/Python 3] DFS, BFS and Bit Manipulation clean codes w/ analysis.
DFSBFS- inspired by@MichaelZ.Analysis:HashSet cost spaceO(N),dfs()cost spaceO(H)and timeO(N),bfs()cost time and spaceO(N), thereforeFindElements() (dfs() and bf
**DFS**

```java
    private Set<Integer> seen = new HashSet<>();
    
    public FindElements(TreeNode root) {
        dfs(root, 0);
    }
    private void dfs(TreeNode n, int v) {
        if (n == null) return;
        seen.add(v);
        n.val = v;
        dfs(n.left, 2 * v + 1);
        dfs(n.right, 2 * v + 2);
    }
    
    public boolean find(int target) {
        return seen.contains(target);
    }
```
```python
    def __init__(self, root: TreeNode):
        self.seen = set()
        
        def dfs(node: TreeNode, v: int) -> None:
            if node:
                node.val = v    
                self.seen.add(v)
                dfs(node.left, 2 * v + 1)
                dfs(node.right, 2 * v + 2)
            
        dfs(root, 0)
        
    def find(self, target: int) -> bool:
        return target in self.seen
```

----

**BFS** - inspired by **@MichaelZ**.
```java
    private Set<Integer> seen = new HashSet<>();
    
    public FindElements(TreeNode root) {
        if (root != null) {
            root.val = 0;
            bfs(root);
        }
    }
    
    public boolean find(int target) {
        return seen.contains(target);
    }
    
    private void bfs(TreeNode node) {
        Queue<TreeNode> q = new LinkedList<>();
        q.offer(node);
        while (!q.isEmpty()) {
            TreeNode cur = q.poll();
            seen.add(cur.val);
            if (cur.left != null) {
                cur.left.val = 2 * cur.val + 1;
                q.offer(cur.left);
            }
            if (cur.right != null) {
                cur.right.val = 2 * cur.val + 2;
                q.offer(cur.right);
            }
        }
    }
```
```python
    def __init__(self, root: TreeNode):

        def bfs(root: TreeNode) -> None:
            dq = collections.deque([root])
            while dq:
                node = dq.popleft()
                self.seen.add(node.val)
                if node.left:
                    node.left.val = 2 * node.val + 1
                    dq.append(node.left)
                if node.right:
                    node.right.val = 2 * node.val + 2
                    dq.append(node.right)
            
        self.seen = set()
        if root:
            root.val = 0
            bfs(root)
        
    def find(self, target: int) -> bool:
        return target in self.seen    
```

**Analysis:**
HashSet cost space `O(N)`, *dfs()* cost space `O(H)` and time `O(N)`, *bfs()*  cost time and space `O(N)`, therefore

*FindElements() (dfs() and bfs()) cost*
time & space: `O(N)`.

*find() cost*
time & space: `O(1)` excluding the space of HashSet.

Where `N` is the total number of nodes in the tree, `H` is the height of the binary tree.

----

**Bit Manipulation**
```java
    private TreeNode root;

    public FindElements(TreeNode root) {
        dfs(root, 0);
        this.root = root;
    }

    private void dfs(TreeNode n, int val) {
        if (n == null) {
            return;
        }
        n.val = val;
        dfs(n.left, val * 2 + 1);
        dfs(n.right, val * 2 + 2);
    }

    public boolean find(int target) {
        TreeNode n = root;
        for (int oneBitMask = Integer.highestOneBit(++target) >> 1; 
                oneBitMask > 0; oneBitMask >>= 1) {
            if (n != null ) {
                n = (target & oneBitMask) == 0 ? n.left : n.right;
            }
        }
        return n != null;
    }
```
```python
    def __init__(self, root: Optional[TreeNode]):
        def dfs(node: TreeNode, val: int) -> None:
            if node:
                node.val = val
                dfs(node.left, val * 2 + 1)
                dfs(node.right, val * 2 + 2)
        dfs(root, 0)
        self.root = root
    def find(self, target: int) -> bool:
        target += 1
        node = self.root
        for i in reversed(range(target.bit_length() - 1)):
            if node:
                if ((target >> i) & 1) == 0:
                    node = node.left
                else:
                    node = node.right
        return node is not None
```
**Analysis:**
*dfs()* cost space `O(H)` and time `O(N)`, therefore

*FindElements() (dfs()) cost*
time: `O(N)`, space `O(H)`.

*find() cost:*
time: `O(log(target))`, space: `O(1)`.

Where `N` is the total number of nodes in the tree, `H` is the height of the binary tree.
['Depth-First Search', 'Breadth-First Search', 'Binary Tree', 'Java', 'Python3']