1261. 在受污染的二叉树中查找元素 【二叉树节点的位运算】target.bit_length()。30 - __builtin_clz(target)

34 阅读2分钟

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

# 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:  # 空间 复杂度  O(n)

    def __init__(self, root: Optional[TreeNode]): # O(n)
        self.valSet = set()
        self.dfs(root, 0)

        # BFS 超内存  速度快 但 占用内存大   DFS: 内存少 慢
        # self.valSet = set()
        # q = [(root, 0)]
        # while q:
        #     node, val = q.pop()
        #     self.valSet.add(val)
        #     if root.left:
        #         root.left.val = 2 * val + 1
        #         q.append((root.left, root.left.val))
        #     if root.right:
        #         root.right.val = 2 * val + 2 
        #         q.append((root.right, root.right.val))

    def find(self, target: int) -> bool:  #  O(1)
        return target in self.valSet      

    def dfs(self, node, val):
        if not node:
            return 

        node.val = val 
        self.valSet.add(val)
        self.dfs(node.left, 2 * val + 1)
        self.dfs(node.right, 2 * val + 2) 


# Your FindElements object will be instantiated and called as such:
# obj = FindElements(root)
# param_1 = obj.find(target)

image.png

/**
 * 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 {
private:
    unordered_set<int> valSet;

    void dfs(TreeNode* node, int val){
        if (!node){
            return;
        }
        node->val = val;
        valSet.insert(val);
        dfs(node->left, val * 2 + 1);
        dfs(node->right, val * 2 + 2);
    }
public:
    FindElements(TreeNode* root) {
        dfs(root, 0);
    }
    
    bool find(int target) {
        return valSet.count(target) > 0;
        // return valSet.contains(target);

    }
};

/**
 * Your FindElements object will be instantiated and called as such:
 * FindElements* obj = new FindElements(root);
 * bool param_1 = obj->find(target);
 */

image.png

参考链接

# 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: # 空间复杂度 O(1)
    # 通过 奇偶 判断 分左右, 位运算 比 求余 运算快
    def __init__(self, root: Optional[TreeNode]):  # O(1)
        self.root = root

    def find(self, target: int) -> bool:  # O(min(h, log target))
        target += 1
        cur = self.root 
        for i in range(target.bit_length() - 2, -1, -1):
            bit = (target >> i) & 1
            # 偶数 左 奇数 右
            cur = cur.right if bit else cur.left
            if not cur:
                return False
        return True 


# Your FindElements object will be instantiated and called as such:
# obj = FindElements(root)
# param_1 = obj.find(target)

image.png

/**
 * 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 {
    TreeNode* root;
public:
    FindElements(TreeNode* root): root(root) { }// 注意 C++ 的初始化!!
    
    bool find(int target) {
        ++target;
        TreeNode* cur = root;
        for (int i = 30 - __builtin_clz(target); i >= 0; --i){// __builtin_clz(target):返回 target 的二进制表示形式中前导 0 的个数
            int bit = target >> i & 1;
            cur = bit ? cur->right : cur->left;
            if (!cur){
                return false;
            }
        }
        return true;
    }
};

/**
 * Your FindElements object will be instantiated and called as such:
 * FindElements* obj = new FindElements(root);
 * bool param_1 = obj->find(target);
 */