Day14:平衡二叉树,所有路径,节点个数 - 教程

1.110. 平衡二叉树

自上而下递归法:

无脑递归法:由于每个节点都要重新计算左右子树高度,有大量重复计算,复杂度O(n²)

这里注意要递归判断每个节点的左右子树,而非仅判断根节点

class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        if not root:
            return True
        left_height = self.height(root.left)
        right_height = self.height(root.right)
        #用括号可以换行
        return (abs(left_height - right_height) <= 1 and
                self.isBalanced(root.left) and
                self.isBalanced(root.right))
    def height(self, node):
        if not node:
            return 0
        return max(self.height(node.left), self.height(node.right)) + 1

自下而上递归法:

上面的isBalanced方法是自上而下,而height方法是自下而上的,height是一定要计算的,能不能写一个函数自下而上,一边记算高度一边判断平衡呢,这样就将复杂度降为o(n)了,很自然就想到了下面的方法:

在height函数里加一个返回值就行

class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        def check(node):
            if not node:
                return 0, True
            left_height, left_balanced = check(node.left)
            right_height, right_balanced = check(node.right)
            return (max(left_height, right_height) + 1,
                abs(left_height - right_height) < 2 and
                left_balanced and right_balanced)
        return check(root)[1]

还有一个用-1来表示"不平衡"的方法,可以提前终止代码,不学了

2.257. 二叉树的所有路径

DFS,遇到叶子节点保存路径,没有就继续向前遍历,保存路径之后退回到上一个节点

这里容易错的:拼接需要先转化为str

class Solution:
    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        res = []
        path = []
        def dfs(node):
            if not node:
                return
            path.append(str(node.val))
            if not node.left and not node.right:
                res.append("->".join(path))
            else:
                dfs(node.left)
                dfs(node.right)
            path.pop()
        dfs(root)
        return res

3.404. 左叶子之和

怎么判断是否为左叶子:dfs遍历到该节点的时候应该知道该节点是否为左子节点,而不是遍历到再判断,左右只能通过上一个节点判断,所以想到给dfs的输入增加一个flag信息is_left:

class Solution:
    def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
        self.sum = 0
        def dfs(node, is_left):
            if not node:
                return
            if is_left and (not node.left and not node.right):
                self.sum += node.val
            if node.left:
                dfs(node.left, True)
            if node.right:
                dfs(node.right, False)
        dfs(root, False)
        return self.sum

4.222. 完全二叉树的节点个数

层序遍历

class Solution:
    def countNodes(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
        queue = deque([root])
        self.cnt = 0
        while queue:
            node = queue.popleft()
            self.cnt += 1
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        return self.cnt

posted on 2026-01-20 17:55  ljbguanli  阅读(0)  评论(0)    收藏  举报