代码随想录|Day15|二叉树04|110.平衡二叉树、257.二叉树的所有路径、404.左叶子之和

110.平衡二叉树

什么是平衡二叉树?

对于平衡二叉树中的任何一个节点,其左右子树的高度差不超过1

前序、中序还是后序?

求二叉树的高度需要使用后序遍历,通过求出左右子树的高度后,返回给父节点。

 举一个例子,根节点6的左子树高度是多少?

按照后序,首先定位到根节点6的左子节点2,以节点2为根节点的子树的高度是多少?

按照后序,首先定位到根节点2的左子节点0,以节点0为根节点的子树的高度是多少?

按照后序,以节点0为根节点的子树,没有左右子节点,接着访问中节点,也就是节点0,高度为1

至此,以节点2为根节点的子树的左子树高度为1

同理,以节点2为根节点的子树的右子树高度为2

因此,根节点6的左子树的高度为 max(1, 2) + 1 = 3

class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:

        def height(node):
            # 空节点,高度为0
            if not node: return 0
            # 递归计算左子树和右子树的高度
            left_height = height(node.left)
            right_height = height(node.right)
            # 判断当前树是否平衡
            # 如果左子树或者右子树不平衡,则当前树不平衡
            # 如果左子树和右子树平衡,但高度差超过1,则当前树不平衡
            # 如果当前树平衡,返回当前树的高度
            if left_height == -1: return -1
            if right_height == -1: return -1
            if abs(left_height - right_height) > 1: return -1
            return max(left_height, right_height) + 1
        
        return height(root) != -1

# 我们可以看到,
# 对于一课树,需要先计算其左右子树的高度
# 接着才可以判断此树是否平衡
# 因此采用后序遍历

​​​​​​​257.二叉树的所有路径

需要探索从根节点到每个叶子节点的所有可能路径。在这个过程中,递归地遍历树的每个节点,沿途记录路径。当我们到达一个叶子节点时,我们找到了一条完整的路径。此时,我们需要“回溯”以去探索其他分支,这就要求我们撤销之前的选择(即从当前路径中移除最近访问的节点),以便路径反映出新的探索方向。

由于需要返回从根节点到叶子结点的路径,自然会选择前序,从上至下依次遍历。

class Solution:
    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        if not root:
            return []
        result = []
        path = []

        def traversal(node, path, result):
            # 中
            path.append(node.val)
            # 到达叶子节点
            if not node.left and not node.right:
                result.append('->'.join(map(str, path)))
                return
            # 左
            if node.left:
                traversal(node.left, path, result)
                path.pop()  # 回溯
            # 右
            if node.right:
                traversal(node.right, path, result)
                path.pop()
        
        traversal(root, path, result)
        return result

404.左叶子之和

什么是左叶子?

1. 是叶子结点

2. 是其父节点的左孩子

因此要判断某节点是否为左叶子,需要遍历到其父节点,并满足以上两个条件。

class Solution:
    def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
        
        sum_left = 0
        # 检查左子节点是否是叶子
        if root.left and not root.left.left and not root.left.right:
            sum_left += root.left.val
        # 如果不是,递归遍历左子树
        else:
            sum_left += self.sumOfLeftLeaves(root.left)
        # 递归遍历右子树
        sum_left += self.sumOfLeftLeaves(root.right)

        return sum_left
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值