Skip to main content

222.计算完全二叉树的节点数

标签: tree, binary-search, depth-first-search

难度: Easy

通过率: 68.18%

原题链接: https://leetcode.com/problems/count-complete-tree-nodes/description/

题目描述

给定一棵完全二叉树的根节点,返回树中节点的数量。

解题思路

完全二叉树的特性是除了最后一层,其余层都是满的且最后一层的节点靠左排列。由于完全二叉树这样特殊的性质,使得在一些子树中递归计算节点数可以更有效。步骤如下:

  1. 首先,计算左子树和右子树的高度。如果左右子树高度相同,则左子树是满的,可以通过公式直接计算节点数:2h12^h - 1,再加上根节点即为左子树的所有节点数。

  2. 如果左右高度不同,说明右子树是个满的二叉树,高度为右子树高,再递归地计算左子树的节点数。这种情况则反过来计算右子树的节点数。

  3. 通过递归上述步骤,最终我们可以在 O(log2n)O(\log^2 n) 时间复杂度以内计算出整个二叉树节点的总数。

代码实现

# Definition for a binary tree node.
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:
# 计算完全二叉树的高度
def getHeight(node):
if not node:
return 0
return 1 + getHeight(node.left)

if not root:
return 0

left_height = getHeight(root.left)
right_height = getHeight(root.right)

if left_height == right_height:
# 左子树是满的,直接计算,它有 2^left_height - 1 个节点,加上根节点
return (1 << left_height) + self.countNodes(root.right)
else:
# 右子树是满的,直接计算,它有 2^right_height - 1 个节点,加上根节点
return (1 << right_height) + self.countNodes(root.left)

复杂度分析

时间复杂度:O(log2n)O(\log^2 n),这是因为每次递归调用都涉及树的高度的计算,而完全二叉树的高度是 O(logn)O(\log n),且递归调用可以在 O(logn)O(\log n) 内完成。

空间复杂度:O(logn)O(\log n),主要是递归调用使用的堆栈空间与树的高度相关。