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. 个人方法
根据完全二叉树最后一层的结点 都集中在该层最左边的若干位置 这一特点来做文章。
- 如果左子树和右子树的高度相同(左、右都是满的),左子树一定是一个 满二叉树,节点个数为 2^h - 1。继续递归判断右子树的左子树和右子树...;
- 若不同,则右子树是满的,继续递归判断左子树的左子树和右子树...。
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) 的遍历快很多;
-