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)

 

posted on 2025-09-14 17:25  axuu  阅读(7)  评论(0)    收藏  举报