灵感来源
- 保持更新,努力学习
- python脚本学习
完全二叉树的节点个数
解题思路
对于完全二叉树,计算节点个数有两种主要方法:
- 简单递归法:直接遍历每个节点,时间复杂度为 O (n),其中 n 是节点数。
- 优化法:利用完全二叉树的特性,时间复杂度为 O (log²n)。
方法二(优化法)思路
完全二叉树的定义是:除了最后一层外,每一层都被完全填充,并且最后一层的节点都尽可能靠左。因此,我们可以通过比较最左和最右路径的深度来判断子树是否为满二叉树:
- 如果左深度等于右深度,说明该子树是满二叉树,节点数为 2^depth - 1。
- 否则,递归计算左子树和右子树的节点数,并加上根节点。
这种方法通过减少不必要的节点访问,将时间复杂度优化到 O (log²n)。
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def countNodes(self, root: TreeNode) -> int:
if not root:
return 0
# 计算左子树的深度
left_depth = 0
node = root
while node.left:
left_depth += 1
node = node.left
# 计算右子树的深度
right_depth = 0
node = root
while node.right:
right_depth += 1
node = node.right
# 如果左右深度相等,说明是满二叉树
if left_depth == right_depth:
return (1 << (left_depth + 1)) - 1 # 2^(depth+1) - 1
# 否则递归计算左右子树的节点数
return 1 + self.countNodes(root.left) + self.countNodes(root.right)
逐行解释
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def countNodes(self, root: TreeNode) -> int:
# 处理空树的基本情况
if not root:
return 0
# 计算左子树的深度(从根到最左叶子节点的路径长度)
left_depth = 0
node = root
while node.left:
left_depth += 1
node = node.left
# 计算右子树的深度(从根到最右叶子节点的路径长度)
right_depth = 0
node = root
while node.right:
right_depth += 1
node = node.right
# 如果左右子树深度相同,说明当前子树是满二叉树
# 满二叉树的节点数为 2^(depth+1) - 1,使用位运算优化计算
if left_depth == right_depth:
return (1 << (left_depth + 1)) - 1
# 若左右深度不同,递归计算左子树和右子树的节点数
# 总节点数 = 根节点(1) + 左子树节点数 + 右子树节点数
return 1 + self.countNodes(root.left) + self.countNodes(root.right)