力扣222. 完全二叉树的节点个数

二分法

  • 思路:
    • 明确完全二叉树的定义: 一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。
    • 如果定义根节点深度为 0,则每层第一个节点到最后一个节点的取值为:
      • 2\^h, 2\^(h+1) - 1

    • 可以一直向左遍历出二叉树的深度,则可知这棵树的节点个数范围;
    • 然后通过二分法,确认编号节点是否在二叉树上:
      • 在二叉树上,更新左边界:min = mid;
      • 不在二叉树上,更新右边界:max = mid - 1;
    • 判断编号 k 节点是否在这颗树上: 如果第 k 个节点位于第 h 层,则 k 的二进制表示包含 h+1位,其中最高位是 1,其余各位从高到低表示从根节点到第 k 个节点的路径,0 表示移动到左子节点,1 表示移动到右子节点。通过位运算得到第 k 个节点对应的路径,判断该路径对应的节点是否存在,即可判断第 k 个节点是否存在。
cpp 复制代码
/**
 * 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 Solution {
public:
    int countNodes(TreeNode* root) {
        if (nullptr == root) {
            return 0;
        }

        int depth = 0;
        TreeNode* node = root;
        while (node->left != nullptr) {
            depth++;
            node = node->left;
        }

        // 2^depth
        int min = 1 << depth;
        // 2^(depth + 1) - 1
        int max = (1 << (depth + 1)) - 1;

        while (min < max) {
            int mid = (max - min + 1) / 2 + min;
            if (exist(root, depth, mid)) {
                min = mid;
            } else {
                max = mid - 1;
            }
        }

        return min;
    }

private:
    bool exist(TreeNode* root, int depth, int k) {
        int bits = 1 << (depth - 1);
        TreeNode* node = root;
        while (node != nullptr && bits > 0) {
            if (!(bits & k)) {
                node = node->left;
            } else {
                node = node->right;
            }

            bits >>= 1;
        }

        return (node != nullptr);
    }
};
相关推荐
Severus_black1 小时前
【C++初阶】Stack、Queue算法题大练兵!
c语言·c++·算法·stl
2601_967979124 小时前
机器学习必修课:经典算法与Python实战
python·算法·机器学习·实战·课程
程序猿打工仔4 小时前
计算机基础(C语言)考编、专技岗
c语言·开发语言·算法
通信小呆呆4 小时前
电子战干扰技术:从“蛮力压制”到“精准欺骗”,再到“认知博弈”
算法·通信·isac
老师我太想进步了20265 小时前
【数据结构-6】算法美学之单链表(1)
数据结构·算法
希望我万事顺遂5 小时前
力扣hot100-滑动窗口最大值
数据结构·算法·leetcode
꧁细听勿语情꧂6 小时前
二叉树余题,排序、直接插入排序、希尔排序
c语言·开发语言·数据结构·算法
是main不是漫6 小时前
【双指针|LeetCode1089 复写零】巧用逆向思路,破解原地覆盖陷阱
数据结构·算法·leetcode
专注仿真16 小时前
知识问答模型用到的算法集详解及代码实例
python·算法·代码·大模型训练·控制算法
罗西的思考17 小时前
【轻量化复刻大模型 / KIMI K3】AttnRes 模块交互式演示
人工智能·算法·机器学习