2025/09/14 【二叉树11】完全二叉树的节点个数
222. 完全二叉树的节点个数 - 力扣(LeetCode)
1.迭代法,层序遍历
class Solution: def countNodes(self, root: Optional[TreeNode]) -> int: count = 0 if not root: return count queue = collections.deque([root]) while queue: for _ in range(len(queue)): node = queue.popleft() count += 1 if node.left: queue.append(node.left) if node.right: queue.append(node.right) return count
2.递归法
解法(1)后序遍历递归
class Solution: def countNodes(self, root: Optional[TreeNode]) -> int: if not root: return 0 leftNodes = self.countNodes(root.left) rightNodes = self.countNodes(root.right) return 1 + leftNodes + rightNodes
精简写法:
class Solution: def countNodes(self, root: Optional[TreeNode]) -> int: if not root: return 0 return 1 + self.countNodes(root.left) + self.countNodes(root.right)
解法(2)前序遍历递归
class Solution: def countNodes(self, root: Optional[TreeNode]) -> int: if not root: return 0 self.count = 0 self.getCount(root) return self.count def getCount(self, node): if not node: return self.count += 1 self.getCount(node.left) self.getCount(node.right)
3.根据完全二叉树特性写的递归法
写法1:
class Solution: def countNodes(self, root: Optional[TreeNode]) -> int: if not root: return 0 left = root.left right = root.right leftDepth = 0 rightDepth = 0 while left: leftDepth += 1 left = left.left while right: rightDepth += 1 right = right.right if leftDepth == rightDepth: return (2<<leftDepth) - 1 return self.countNodes(root.left) + self.countNodes(root.right) + 1
写法1.1:
class Solution: def countNodes(self, root: Optional[TreeNode]) -> int: if not root: return 0 left = root.left right = root.right leftDepth = 1 rightDepth = 1 while left: leftDepth += 1 left = left.left while right: rightDepth += 1 right = right.right if leftDepth == rightDepth: return 2**leftDepth - 1 return self.countNodes(root.left) + self.countNodes(root.right) + 1
知识点:
①. 以下的两种写法不同
写法1:return (2 << leftDepth) - 1 写法2:return 2 ** leftDepth - 1
它们的结果不一样,因为 <<
是移位运算符,而 **
是指数(幂)运算。
解释1:
-
2 << leftDepth
是把数字 2 左移leftDepth
位。 -
位运算规律是:
x << n == x * (2^n)
-
所以
2 << leftDepth == 2 * (2^leftDepth) == 2^(leftDepth + 1)
(2 << n) - 1 == 2 ** (n + 1) - 1
解释2:
-
2 ** leftDepth
是指数运算,直接表示2^leftDepth
进一步的:
(1 << n) == 2 ** n
因为 1 << n
表示二进制数 1
向左移动 n
位,也就是 2^n
。
而 2 << n == 2 * 2^n == 2^(n+1)
。
②错误写法
return 2 << leftDepth - 1
问题出在运算优先级
在 Python 中,-
(减法)优先级高于 <<
(左移)。
所以这行代码等价于:
return 2 << (leftDepth - 1)
写法2:
class Solution: def countNodes(self, root: Optional[TreeNode]) -> int: if not root: return 0 count = 1 left = root.left; right = root.right while left and right: count += 1 left = left.left; right = right.right if not left and not right: return 2**count - 1 return 1 + self.countNodes(root.left) + self.countNodes(root.right)
写法2.2:
class Solution: def countNodes(self, root: Optional[TreeNode]) -> int: if not root: return 0 count = 0 left = root.left; right = root.right while left and right: count += 1 left = left.left; right = right.right if not left and not right: return (2<<count) - 1 return 1 + self.countNodes(root.left) + self.countNodes(root.right)