当前位置: 首页 > news >正文

第20天(简单题 二分查找递归)

打卡第二十天
3道简单题 (简单在哪里....二叉树咋这么难)
image


题目: 给你一棵完全二叉树的根节点root,求出该树的节点个数。


方法一: 递归:完全二叉树只有两种情况,一是满二叉树,二是最后一层叶子节点没有满。
对于情况一,用 2^树深度 - 1 来计算。
对于情况二,分别递归左子树和右子树,递归计算左子树节点数 + 右子树节点数 + 1。

代码:

class Solution {
public:int countNodes(TreeNode* root) {if (root == nullptr){return 0;}TreeNode* left = root->left;//左子树指针TreeNode* right = root->right;//右子树指针int leftDepth = 0, rightDepth = 0;//初始化左右子树深度为0while (left) {  // 求左子树深度left = left->left;leftDepth++;}while (right) { // 求右子树深度right = right->right;rightDepth++;}if (leftDepth == rightDepth) {return (2 << leftDepth) - 1; // (2<<1) 相当于2^2,所以leftDepth初始为0}return countNodes(root->left) + countNodes(root->right) + 1;}
};


方法二: 二分查找+位运算
完全二叉树的最后一层节点编号是连续的,在 [2^level, 2^(level+1)-1] 范围内二分查找最后一个存在的节点
节点编号 k 的二进制表示(去掉最高位的1)就是从根节点到该节点的路径: 0 表示向左,1 表示向右

位运算实现逻辑:
image


代码:

class Solution {
public:int countNodes(TreeNode* root) {if (root == nullptr) {return 0;}// 计算树的高度int level = 0;TreeNode* node = root;while (node->left != nullptr) {level++;node = node->left;}// level层是最底层,节点编号从 2^level 到 2^(level+1)-1int low = 1 << level;                    // 最低可能节点编号:2^levelint high = (1 << (level + 1)) - 1;       // 最高可能节点编号:2^(level+1)-1// 二分查找:在[low, high]范围内找到最后一个存在的节点编号while (low < high) {int mid = (high - low + 1) / 2 + low;  // 向上取整,避免死循环if (exists(root, level, mid)) {low = mid;        // mid存在,说明最终答案 >= mid} else {high = mid - 1;   // mid不存在,说明最终答案 < mid}}return low;  // 此时low == high,就是节点总数}// 判断编号为k的节点是否存在bool exists(TreeNode* root, int level, int k) {int bits = 1 << (level - 1);  // 用于位运算的掩码TreeNode* node = root;// 根据k的二进制表示从高位到低位遍历路径while (node != nullptr && bits > 0) {if (!(bits & k)) {     // 当前位为0,往左走node = node->left;} else {               // 当前位为1,往右走node = node->right;}bits >>= 1;           // 移到下一位}return node != nullptr;   // 如果node不为空,说明该节点存在}
};

int bits = 1 << (level - 1); // 用于位运算的掩码

image

耗时≈两小时 明天继续

http://www.jsqmd.com/news/36045/

相关文章:

  • 20251110周日日记
  • 当前操作系统的应用主题工具类 - C#小函数类推荐
  • 11.6总结
  • 21. 数据库编程
  • 11.3总结
  • 22.网络编程
  • 11.4总结
  • 11.5总结
  • 10.31总结
  • cve-2014-4148 利用样本分析
  • 2025ccpc女生赛题解
  • Day16盒子模型
  • 每日反思(2025年11月9号)
  • OpenOCD简明指南
  • OpenOCD简明指南
  • 2025Dec.居家集训游记
  • 电商财务不求人!一张图看懂工作流程,算清每一笔账 - 智慧园区
  • OI 笑传 #26
  • 20232327 2025-2026-1 《网络与系统攻防技术》实验四实验报告
  • Gas 优化技巧
  • 2025.11.9总结
  • Python与C语言术语及概念差异全景总结
  • Appium vs uiautomator2 优势劣势对比表
  • 基于GF域的多进制QC-LDPC误码率matlab仿真,译码采用EMS算法
  • AtCoder Beginner Contest 431
  • 基于BPSK调制解调和LDPC编译码的单载波相干光传输系统matlab误码率仿真
  • 空间矢量脉宽调制(Space Vector Pulse Width Modulation)SVPWM基础
  • 如何有效衡量开发者生产力:超越代码行数的思考
  • 2025-11-blog
  • 科研项目申报