给出一个完全二叉树,求出该树的节点个数。
说明:
完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
示例:
输入:
1
/ \
2 3
/ \ /
4 5 6
输出: 6
解题思路
这个问题使用递归很好解决,我们只要考虑好如下四种情况就可以很快解决这个问题。
root
为空root.left
和root.right
都不为空root.left
为空,root.right
不为空root.right
为空,root.left
不为空root.left
和root.right
都为空
class Solution:
def countNodes(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
return 0
if root.left and root.right:
return self.countNodes(root.left) + self.countNodes(root.right) + 1
if root.right:
return self.countNodes(root.right) + 1
if root.left:
return self.countNodes(root.left) + 1
return 1
这里如果我们将None
也看做是一个二叉树的话,那么这个问题就变得很容易,只存在
root
为空root
不为空
class Solution:
def countNodes(self, root):
"""
:type root: TreeNode
:rtype: int
"""
return self.countNodes(root.left) + self.countNodes(root.right) + 1 if root else 0
同样的,对于可以用递归解决的问题,我们都应该思考一下怎么可以通过迭代去解决。那这个问题怎么通过迭代解决呢?我们首先要知道
- 二叉树的第n层最多为 2 n 2^{ n} 2n个节点
- 二叉树最多有 2 n + 1 − 1 2^{ n+1 }-1 2n+1−1个节点(满二叉树)
基于这两个性质,我们可以这样思考。如果右子树
的高度等于整棵二叉树的高度-1
的话,那么左子树
一定是一棵满二叉树
,这个时候我们就很容易的计算出总结点数nodes=2**(h)-1 + 1 +右子树节点数
(这里的+1
表示root
节点)。如果右子树
的高度不等于整棵二叉树的高度-1
的话,那么左子树
不一定是一棵满二叉树
,但是有一点可以确定,右子树
一定是一棵满二叉树
,这个时候我们就很容易的计算出总结点数nodes=2**(h-1)-1 + 1 +左子树节点数
(这里的+1
表示root
节点)。根据这个思路我们只要不断循环下去直到root==None
结束。
class Solution:
def countNodes(self, root):
"""
:type root: TreeNode
:rtype: int
"""
def height(t):
h = -1
while t:
h += 1
t = t.left
return h
h = height(root)
nodes = 0
while root:
if height(root.right) == h - 1:
nodes += 2**h
root = root.right
else:
nodes += 2**(h - 1)
root = root.left
h -= 1
return nodes
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!