问题描述
给你一棵 完全二叉树 的根节点 root
,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h
层,则该层包含 1~ 2h
个节点。
示例 1:
输入:root = [1,2,3,4,5,6]
输出:6
示例 2:
输入:root = []
输出:0
示例 3:
输入:root = [1]
输出:1
提示:
- 树中节点的数目范围是
[0, 5 * 104]
0 <= Node.val <= 5 * 104
- 题目数据保证输入的树是 完全二叉树
进阶:遍历树来统计节点是一种时间复杂度为 O(n)
的简单解决方案。你可以设计一个更快的算法吗?
普通二叉树
首先按照普通二叉树的逻辑来求。
这道题目的递归法和求二叉树的深度写法类似, 而迭代法,层序遍历模板稍稍修改一下,记录遍历的节点数量就可以了。
递归遍历的顺序依然是后序(左右中)。
递归
后序遍历,考虑递归三部曲。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Solution { private: int getNodesNum(TreeNode* cur) { if (cur == NULL) return 0; int leftNum = getNodesNum(cur->left); int rightNum = getNodesNum(cur->right); int treeNum = leftNum + rightNum + 1; return treeNum; } public: int countNodes(TreeNode* root) { return getNodesNum(root); } };
|
- 时间复杂度:O(n)
- 空间复杂度:O(logn),算上了递归系统栈占用的空间
迭代
只要模板少做改动,加一个变量result,统计节点数量就可以了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution { public: int countNodes(TreeNode* root) { queue<TreeNode*> que; if (root != NULL) que.push(root); int result = 0; while (!que.empty()) { int size = que.size(); for (int i = 0; i < size; i++) { TreeNode* node = que.front(); que.pop(); result++; if (node->left) que.push(node->left); if (node->right) que.push(node->right); } } return result; } };
|
- 时间复杂度:O(n)
- 空间复杂度:O(n)
完全二叉树
核心思路
完全二叉树只有两种情况:
-
是满二叉树。可以直接用 2树深度−1 来计算,注意这里根节点深度为1。
-
最后一层叶子节点没有满。分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。
判断其子树是不是满二叉树,如果是则利用公式计算这个子树(满二叉树)的节点数量,如果不是则继续递归,
实现要点
如何判断一棵树是不是完全二叉树?
在完全二叉树中,如果递归向左遍历的深度等于递归向右遍历的深度,那说明就是满二叉树。
code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 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; while (left) { left = left->left; leftDepth++; } while (right) { right = right->right; rightDepth++; } if (leftDepth == rightDepth) { return (2 << leftDepth) - 1; } return countNodes(root->left) + countNodes(root->right) + 1; } };
|
- 时间复杂度:O(logn×logn)
- 空间复杂度:O(logn)