代码随想录算法训练营day15| 110.平衡二叉树 257.二叉树的所有路径 404.左叶子之和 222.完全二叉树的节点个数

学习资料:https://programmercarl.com/0110.平衡二叉树.html#算法公开课

平衡二叉树:任意一个节点的左右子树高度差不超过1
左叶子:是叶子节点,且是其父节点的左节点
完全二叉树:上层均满,底层的节点从左到右连续
满二叉树:每层都是满的,节点总数为 (2^k + 1)
语法: 2<<1 是 2^2

学习记录:
110.平衡二叉树 (巧:当发现这个节点不平衡后,返回-1,再向上依次传递-1)

点击查看代码
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def isBalanced(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        node_height = self.getHeight(root)
        if node_height != -1:
            return True
        else:
            return False


    def getHeight(self, node):
        """
        递归法+后序遍历
        对于平衡二叉树而言,计算高度函数的逻辑是:
        当节点左右子树高度差超过1则该节点为不平衡,高度记为-1,则向上传递时,该节点作为上面的子树一直传递-1即可;
        而当节点左右子树高度不超过1,则记录节点的真实高度,即1+max(左右子树)
        """
        if not node:
            return 0
        left_h = self.getHeight(node.left)
        if left_h == -1:
            return -1
        right_h = self.getHeight(node.right)
        if right_h == -1:
            return -1
        if abs(left_h-right_h)>1:
            node_h = -1
        else:
            node_h = 1 + max(left_h, right_h)
        return node_h
        

257.二叉树的所有路径(递归+回溯)

点击查看代码
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def traversal(self, node, path, result):
        """
        前序遍历+回溯+递归
        """
        path.append(node.val)   # 存放当下考虑的节点,后面要弹出,相当于回到上一个节点
        if not node.left and not node.right:  # 叶子节点
            sPath = '->'.join(map(str, path))
            result.append(sPath)
            return
        if node.left:
            self.traversal(node.left, path, result)   # 递归
            path.pop()                                # 回溯,每考虑完一个节点就要返回到上一个节点
        if node.right:
            self.traversal(node.right, path, result)
            path.pop()

    def binaryTreePaths(self, root):
        """
        :type root: TreeNode
        :rtype: List[str]
        """
        result = []
        path = []
        if not root:
            return result
        self.traversal(root, path, result)  # 因为list可以传递,traversal就不返回值了,只要处理list就行
        return result
        

404.左叶子之和(判断一个节点是否为左叶子,要在它的父节点处判断;后序遍历)

点击查看代码
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def sumOfLeftLeaves(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        # 如果节点是Null,那它没有左叶子
        if not root:
            return 0
        # 如果节点是叶子,那它没有左叶子
        if not root.left and not root.right:
            return 0
        
        # 那剩余情况的节点都有左叶子
        # 开始后序遍历,左右根,递归法
        # 左:节点的左子树中的左叶子的值
        left_num = self.sumOfLeftLeaves(root.left)     # 递归
        if root.left and not root.left.left and not root.left.right:   # 此节点root是判断它的左子节点root.left是否为左叶子(是叶子节点,且,为父节点的左子节点)
            left_num = root.left.val   # 提取左叶子的值
        
        # 右:节点的右子树的左叶子的值
        right_num = self.sumOfLeftLeaves(root.right)

        # 根:节点左子树的左叶子的值和右子树的左节点的值求和
        sum_num = left_num + right_num
        return sum_num
        

222.完全二叉树的节点个数(对于完全二叉树有个特殊解法,找到其中的满二叉树,那下面的直接2^k-1就算出来了;后序遍历)

点击查看代码
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def countNodes(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        # 后序遍历+递归法
        # 终止条件1:node为null
        if not root:
            return 0
        # 终止条件2:找到其中的满二叉树,这部分的节点数可用公式(2^k + 1)计算
        left = root.left
        right = root.right
        left_depth = 0
        right_depth = 0
        while left:              # 遍历root左子树的所有左节点
            left = left.left
            left_depth += 1
        while right:             # 遍历root右子树的所有右节点
            right = right.right
            right_depth += 1
        if left_depth == right_depth:      # 在完全二叉树的基础上,当左侧深度等于右侧深度,则此部分为满二叉树
            return (2 << left_depth) - 1    # 语法 2<<1是2^2,所以上面深度初始值记为0
        
        # 处理逻辑:后序,左右根
        left_num = self.countNodes(root.left)     # 当不是完全二叉树时,就向节点的左右子树递归,
        right_num = self.countNodes(root.right)
        total_num = left_num + right_num + 1
        return total_num 
            
        

PS:今天的有点费脑子,有点尝到递归的味道了,好像听懂了又好像没听懂,就感觉递归很方便
今天吃到了好吃的外卖,有锅气的土豆肉丝炒饭,和面泡软了的牛肉拉面
又是被审判的一次面试,是不是找不到工作了,我严重怀疑
勒!

posted @   Tristan241001  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示