LeetCode222_完全二叉树的结点个数

LeetCode222_完全二叉树的结点个数

  • [标签:#位运算 #树 #二分查找 #二叉树](#位运算 #树 #二分查找 #二叉树)
    • [Ⅰ. 题目](#Ⅰ. 题目)
    • [Ⅱ. 示例](#Ⅱ. 示例)
  • [0. 个人方法](#0. 个人方法)

标签:#位运算 #树 #二分查找 #二叉树

Ⅰ. 题目

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

  • 完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(从第 0 层开始),则该层包含 1~ 2^h 个节点。

Ⅱ. 示例

· 示例 1:

输入:root = [1,2,3,4,5,6]

输出:6

· 示例 2:

输入:root = []

输出:0

· 示例 3:

输入:root = [1]

输出:1

0. 个人方法

根据完全二叉树最后一层的结点 都集中在该层最左边的若干位置 这一特点来做文章。

  1. 如果左子树和右子树的高度相同(左、右都是满的),左子树一定是一个 满二叉树,节点个数为 2^h - 1。继续递归判断右子树的左子树和右子树...;
  2. 若不同,则右子树是满的,继续递归判断左子树的左子树和右子树...。
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 getHeight(TreeNode* root) {
        int h = 0;
        while (root) {
            h++;
            root = root->left;
        }
        return h;
    }

    int countNodes(TreeNode* root) {
        if (!root) return 0;

        int leftHeight = getHeight(root->left);
        int rightHeight = getHeight(root->right);

        if (leftHeight == rightHeight)
            return (1 << leftHeight) + countNodes(root->right);
        else
            return (1 << rightHeight) + countNodes(root->left);
    }
};

PS:"1 << leftHeight" 表示将 1 左移 leftHeight 位,即表示 2leftHeight(左子树的结点数为 2leftHeight-1,根结点为 1)

  • 时间复杂度分析
    • getHeight() 时间是 O(log n)(树高);

    • 每一层递归时 getHeight 被调用两次,最多递归 log n 层;

    • 总时间复杂度为 O((log n)^2) ------ 比普通 O(n) 的遍历快很多;

相关推荐
No0d1es2 小时前
电子学会青少年软件编程(C/C++)5级等级考试真题试卷(2024年6月)
c语言·c++·算法·青少年编程·电子学会·五级
DjangoJason3 小时前
C++ 仿RabbitMQ实现消息队列项目
开发语言·c++·rabbitmq
Swift社区4 小时前
Swift 实战:实现一个简化版的 Twitter(LeetCode 355)
leetcode·swift·twitter
weixin_307779135 小时前
VS Code配置MinGW64编译GNU 科学库 (GSL)
开发语言·c++·vscode·算法
蒋星熠7 小时前
C++零拷贝网络编程实战:从理论到生产环境的性能优化之路
网络·c++·人工智能·深度学习·性能优化·系统架构
CHANG_THE_WORLD8 小时前
# C++ 中的 `string_view` 和 `span`:现代安全视图指南
开发语言·c++
雨落倾城夏未凉8 小时前
9.c++new申请二维数组
c++·后端
雨落倾城夏未凉8 小时前
8.被free回收的内存是立即返还给操作系统吗?为什么?
c++·后端
雨落倾城夏未凉8 小时前
6.new和malloc的区别
c++·后端
郝学胜-神的一滴8 小时前
深入理解QFlags:Qt中的位标志管理工具
开发语言·c++·qt·程序人生