个人算法成长之路四十六!!!定期更新一些刷题过程中个人的思路以及理解。有兴趣的朋友们可以互动交流哈~
题目:
222. 完全二叉树的节点个数
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
示例 1:
输入:root = [1,2,3,4,5,6]
输出:6
示例 2:
输入:root = []
输出:0
示例 3:
输入:root = [1]
输出:1
解题思路:
对于一个完全二叉树 complete binary tree:
-
它的所有子树都是完全二叉树
-
有的子树是 perfect binary tree
-
perfect binary tree 的节点个数很好计算:2^h-1,h为高度
-
如果不是 perfect binary tree,那就是规模小一点的完全二叉树,递归处理。
完全二叉树 1
/ \
完美二叉树 2 3
/ \ /
4 5 6
-------------------- 其实左右子树至少有一个是 full binary tree
1 完全二叉树
/ \
2 3 完美二叉树
/
4
所以对于每个节点 root,都判断一下它是否是满二叉树——左侧的高度 == 右侧的高度。
full binary tree 1
/ \
2 3
/ \ / \
左侧深度 3 4 5 6 7 右侧深度 3
代码
func countNodes(root *TreeNode) int { // 返回以root为根节点的子树的节点个数
if root == nil { // 递归的出口
return 0
}
lH, rH := 0, 0 // 两侧高度
lNode, rNode := root, root // 两个指针
for lNode != nil { // 计算左侧高度
lH++
lNode = lNode.Left
}
for rNode != nil { // 计算右侧高度
rH++
rNode = rNode.Right
}
if lH == rH { // 当前子树是满二叉树,返回出节点数
return 1<<lH - 1 // 左移n位就是乘以2的n次方
}
// 当前子树不是完美二叉树,只是完全二叉树,递归处理左右子树
return 1 + countNodes(root.Left) + countNodes(root.Right)
}