二叉树递归遍历解决问题刷题 (二)

1.如果让你在二叉树的「树枝」上做文章,那么用遍历的思维模式解题是比较自然的想法 可以是求和问题也可以是路径问题,路径问题可以理解为回溯两次,在叶子结点那里的回溯,是把记录的一个叶子节点删除

2.如果让你在二叉树中的某些节点上做文章,一般来说也可以直接用遍历的思维模式。 某些节点符合一些特质,找到这些符合特质的节点,用递归遍历的思想来写

404. 左叶子之和 左叶子就是某些结点

class Solution:

    def __init__(self):
        self.sum = 0

    # 记录左叶子之和
    # int sum = 0; # This is handled in the constructor now

    # 二叉树遍历函数
    def traverse(self, root):
        if root is None:
            return
        
        if root.left is not None and  root.left.left is None and root.left.right is None:
            # 找到左侧的叶子节点,记录累加值
            self.sum += root.left.val

        # 递归框架
        self.traverse(root.left)
        self.traverse(root.right)

    def sumOfLeftLeaves(self, root: TreeNode) -> int:
        self.traverse(root)
        return self.sum

在这道题目中,我们需要计算二叉树中所有左叶子节点的和。因为我们只是需要遍历整棵树,并累加所有左叶子节点的值,而不需要修改或恢复树的状态,所以不需要回溯。以下是详细解释:

回溯法

回溯是一种常用于解决组合问题的算法技术。回溯会尝试所有可能的解决方案,找到所有可行解。在回溯过程中,我们需要记住当前的状态,并在离开当前状态时恢复到先前的状态。这种技术常用于路径问题或需要恢复先前状态的问题。

为什么这题不需要回溯

在这道题目中,我们的目标是遍历整棵树并累加所有左叶子节点的值。为了实现这一点,我们可以使用递归遍历树的每个节点。当我们找到一个左叶子节点时,将其值累加到 self.sum 中。 求和问题不需要回溯12

如果你对二叉树足够熟悉,可以想到很多方式通过递归函数得到层序遍历结果

class Solution:
    res = []

    def levelTraverse(self, root):
        if root is None:
            return self.res
        # root 视为第 0 层
        self.traverse(root, 0)
        return self.res

    def traverse(self, root, depth):
        if root is None:
            return
        # 前序位置,看看是否已经存储 depth 层的节点了
        if len(self.res) <= depth:
            # 第一次进入 depth 层
            self.res.append([])
        # 前序位置,在 depth 层添加 root 节点的值
        self.res[depth].append(root.val)
        self.traverse(root.left, depth + 1)
        self.traverse(root.right, depth + 1)

这段代码通过 DFS 模仿层序遍历,将二叉树每层的节点值收集到一个列表中。 还是dfs,不过获得了层序遍历的结果。

写dfs用遍历的方法思考时候,想想dfs需要接受的输入有哪些,要记录父节点,可以把父节点也加进去输入。

993. 二叉树的堂兄弟节点

class Solution:
    def __init(self):
        self.depth_x = 0
        self.depth_y = 0
        self.parent_x = None 
        self.parent_y = None 
        self.x = 0 
        self.y = 0 
    def traverse(self, root, depth, parent):#由于要记录的数据有depth,所以depth也作为一个要记录的参数写进来
        if root is None:
            return 
        if self.x == root.val:
            self.depth_x = depth 
            self.parent_x = parent 
        if self.y == root.val:
            self.depth_y = depth 
            self.parent_y = parent 
        self.traverse(root.left, depth + 1, root)
        self.traverse(root.right, depth + 1, root)
    def isCousins(self, root: Optional[TreeNode], x: int, y: int) -> bool:
        self.x = x 
        self.y = y 
        self.traverse(root, 0, None)
        if self.depth_x == self.depth_y and self.parent_x != self.parent_y:
            return True 
        return False 
    

python命名风格命名规则在编程中非常重要,因为它影响代码的可读性和可维护性。Python 社区推荐使用 PEP 8 风格指南,它建议使用蛇形命名法(snake_case),即所有字母小写,单词之间用下划线分隔。

命名规则说明

  1. snake_case(蛇形命名法)
    • 用于变量名和函数名。
    • 例如:depth_x, depth_y, calculate_depth.
  2. CamelCase(驼峰命名法)
    • 用于类名。
    • 例如:TreeNode, Solution.(而java的第一个名字不大写,看着不太顺眼)

在练习leetcode时候每一遍自己都把命名改过来,统一代码风格。

祖父节点值为偶数的节点和

遍历一遍二叉树,对于节点值为偶数的节点,累加它的孙子节点的值即可。 从头往下找容易

class Solution:
    def __init__(self):
        self.sum = 0 
    def sumEvenGrandparent(self, root: TreeNode) -> int:
        self.traverse(root)
        return self.sum 
    def traverse(self, root):
        if root is None:
            return 
        if root.val % 2 == 0:
            if root.left is not None:
                if root.left.left is not None:
                    self.sum += root.left.left.val 
                if root.left.right is not None:
                    self.sum += root.left.right.val 
            if root.right is not None:
                if root.right.left is not None:
                    self.sum += root.right.left.val
                if root.right.right is not None:
                    self.sum += root.right.right.val 
        self.traverse(root.left)
        self.traverse(root.right)
        #求和就可以,没有回溯这一步,
    

1448.统计二叉树中好节点的数目

想一想在遍历的过程中好节点应该满足的属性 就是好节点的val >= path_max , path_max参数用来更新当前路径的最大值,并且之后更新path_max

class Solution:
    def __init__(self):
        self.count = 0 
    def traverse(self, root, path_max):
        if root is None:
            return 
        if root.val >= path_max:
            self.count += 1 
        path_max = max(root.val, path_max)

        self.traverse(root.left, path_max)
        self.traverse(root.right, path_max)
    def goodNodes(self, root: TreeNode) -> int:
        self.traverse(root, root.val)
        return self.count
  • 31
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值