Given the root of a complete binary tree, return the number of the nodes in the tree. According to Wikipedia, every level, except possibly the last, is completely filled in a complete binary tree, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h. Design an algorithm that runs in less than O(n) time complexity.
 
  完全二叉树:设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边
题目要求时间复杂度小于O(n) 该如何处理呢?
/**
* 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) {
//为啥要设计一个时间复杂度小于n的算法
//完全二叉树的特性 o(n)的比较好写
// 先写o(n)复杂的的
int res=0;
if(root==nullptr) return res;
stack<TreeNode* > dp;
dp.push(root);
while(!dp.empty()){
TreeNode* node=dp.top();
res++;
dp.pop();
if(node->left!=nullptr){
dp.push(node->left);
}
if(node->right!=nullptr){
dp.push(node->right);
}
}
return res;
}
};
  对于完全二叉树,去掉最后一层,就是一棵满二叉树,我们知道高度为 h 的满二叉树结点的个数为 2^h - 1 个,所以要知道一棵完全二叉树的结点个数,只需知道最后一层有多少个结点。而完全二叉树最后一层结点是从左至右连续的,所以我们可以依次给它们编一个号,然后二分搜索最后一个叶子结点。我是这样编号的,假设最后一层在 h 层,那么一共有 2^(h-1) 个结点,一共需要 h - 1 位来编号,从根结点出发,向左子树走编号为 0, 向右子树走编号为 1,那么最后一层的编号正好从0 ~ 2^(h-1) - 1。复杂度为 O(h*log(2^(h-1))) = O(h^2)。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isOK(TreeNode *root, int h, int v) {
TreeNode *p = root;
for (int i = h - 2; i >= 0; --i) {
if (v & (1 << i)) p = p->right;
else p = p->left;
}
return p != NULL;
} int countNodes(TreeNode* root) {
if (root == NULL) return 0;
TreeNode *p = root;
int h = 0;
while (p != NULL) {
p = p->left;
++h;
}
int l = 0, r = (1 << (h - 1)) - 1, m;
while (l <= r) {
m = l + ((r - l) >> 1);
if (isOK(root, h, m)) l = m + 1;
else r = m - 1;
}
return (1 << (h - 1)) + r;
}
};

【leetcode】222. Count Complete Tree Nodes(完全二叉树)的更多相关文章

  1. [leetcode]222. Count Complete Tree Nodes完全二叉树的节点数

    /* 满二叉树的特点是2^n-1,对于完全二叉树,一个node如果左右子树深度相同,那么 是一个满二叉树.如果不是,那就把node算上,继续往下看,下边的可能是满二叉树 由于完全二叉树中有一些子满二叉 ...

  2. [LeetCode] 222. Count Complete Tree Nodes 求完全二叉树的节点个数

    Given a complete binary tree, count the number of nodes. Note: Definition of a complete binary tree ...

  3. Java for LeetCode 222 Count Complete Tree Nodes

    Given a complete binary tree, count the number of nodes. Definition of a complete binary tree from W ...

  4. (medium)LeetCode 222.Count Complete Tree Nodes

    Given a complete binary tree, count the number of nodes. Definition of a complete binary tree from W ...

  5. 【刷题笔记】LeetCode 222. Count Complete Tree Nodes

    题意 给一棵 complete binary tree,数数看一共有多少个结点.做题链接 直观做法:递归 var countNodes = function(root) { if(root===nul ...

  6. 222 Count Complete Tree Nodes 完全二叉树的节点个数

    给出一个完全二叉树,求出该树的节点个数.完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置.若最底层为第 h ...

  7. leetcode 222.Count Complete Tree Nodes

    完全二叉树是从左边开始一点点填充节点的,因此需要计算所有的节点的个数. 则分别从左边和右边来进行传递的,当左右是完全二叉树的时候,其节点个数就是pow(2,h)-1. /** * Definition ...

  8. leetcode 958. Check Completeness of a Binary Tree 判断是否是完全二叉树 、222. Count Complete Tree Nodes

    完全二叉树的定义:若设二叉树的深度为h,除第 h 层外,其它各层 (1-h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树. 解题思路:将树按照层进行遍历,如果 ...

  9. 【LeetCode】222. Count Complete Tree Nodes 解题报告(Python)

    [LeetCode]222. Count Complete Tree Nodes 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个 ...

  10. 【刷题-LeetCode】222. Count Complete Tree Nodes

    Count Complete Tree Nodes Given a complete binary tree, count the number of nodes. Note: Definition ...

随机推荐

  1. 云主机新增swap分区

    云主机内存不够用,如何新增swap 分区. 如何启用swap分区? 步骤如下: 1.查看当前系统中是否已经启用swap分区 1 2 cat /proc/swaps    top 2.如果没有启用swa ...

  2. Zabbix5.0实现监控系统登陆失败告警

    环境zabbix5.0,配置思路,通过添加监控项和触发器实现,监控项监控对应的日志文件,触发器过滤日志文件中的关键字,当出现failed时就发出告警. 监控项配置 类型选择zabbix客户端主动式,键 ...

  3. /etc/passwd 和 /etc/shadows 详解

    linux操作系统上的用户如果需要登录主机,当其输入用户名和密码之后: 首先在/etc/passwd文件中查找是否有你的账号,如果没有无法登录,如果有的话将该用户的UID和GID读出来,此外将此用户的 ...

  4. 不破不立,祝贺EDG夺得S11冠军。这一夜,我看到太多Flag成真

      在昨晚11月6号夜进行的2021英雄联盟S11总决赛中,中国战队EDG夺冠!全国各地高校的男生宿舍像过年一般庆祝夺冠,高呼:EDG世界冠军!   前三局1:2的劣势下,第四局十分胶着,最终EDG顽 ...

  5. C++ 函数模板实现原理剖析

    C++ 函数模板实现机制原理剖析 重点 编译器并不是把函数模板处理成能够处理任意类的函数 编译器从函数模板通过具体类型来产生不同的函数 编译器会对函数模板进行两次编译 (1)在声明的位置对模板代码进行 ...

  6. webpack 之 js语法检查eslint

    webpack 之 js语法检查eslint // 用来拼接绝对路径的方法 const {resolve} = require('path') const HtmlWebpackPlugin = re ...

  7. 概述C# virtual修饰符

    摘要:C#是继C++和Java语言后的又一面向对象的语言,在语法结构,C#有很多地方和C++及Java相似,但是又不同于它们,其中一些关键特别需要引起我们的注意. C# virtual修饰符用于修改方 ...

  8. Salesforce Consumer Goods Cloud 浅谈篇三之 行动计划(Action Plan)相关配置

    本篇参考: https://v.qq.com/x/page/f0772toebhd.html https://v.qq.com/x/page/e0772tsmtek.html https://v.qq ...

  9. Three.js实现脸书元宇宙3D动态Logo

    背景 Facebook 近期将其母公司改名为 Meta,宣布正式开始进军 元宇宙 领域.本文主要讲述通过 Three.js + Blender 技术栈,实现 Meta 公司炫酷的 3D 动态 Logo ...

  10. [loj2049]网络

    考虑整体二分,假设二分到区间$[l,r]$,即要对若干个询问,判断这些询问的答案与$mid=\lfloor\frac{l+r}{2}\rfloor$的关系 根据题意,答案$\le mid$等价于重要度 ...