力扣每日练习(3.15)补

112. 路径总和

解题思路:遍历出每条路径,使得总和为目标值。如果找到了,就是1.否则为0.

如果遍历到了叶节点,就计算是否达到了目标值;

如果没有遍历到叶节点,就继续往左右子树遍历。

python 复制代码
def hasPathSum(root: TreeNode, targetSum: int) -> bool:
    if not root:
        # 当前节点为空,返回False
        return False

    # 更新目标和
    targetSum -= root.val

    # 如果当前节点是叶子节点,检查目标和是否为0
    if not root.left and not root.right:
        return targetSum == 0

    # 递归检查左右子树
    return hasPathSum(root.left, targetSum) or hasPathSum(root.right, targetSum)

113. 路径总和 II

上一题的进阶,要求记录每条成功路径的具体路径

也就是要新增一个结果list存储所有成功的路径列表,还有每条路径的path。

python 复制代码
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def pathSum(root: TreeNode, targetSum: int) -> List[List[int]]:
    def dfs(node, currentSum, path):
        if not node:
            return
        
        currentSum += node.val
        path.append(node.val)
        
        # 检查是否是叶子节点且当前路径和等于目标和
        if not node.left and not node.right and currentSum == targetSum:
            # 注意这里需要添加path的副本
            result.append(path[:])
        
        # 递归遍历左右子树
        dfs(node.left, currentSum, path)
        dfs(node.right, currentSum, path)
        
        # 回溯,从路径中移除当前节点
        path.pop()

    result = []
    dfs(root, 0, [])
    return result

ai的理解:

想象你在一个迷宫里寻找宝藏,这个迷宫就像是我们的二叉树,宝藏是位于叶子节点的目标和targetSum。你手里有一张纸(这就是我们的path列表),每当你向前走一步,就在纸上记下你的当前位置。当你到达一个死路(叶子节点)但没有找到宝藏时,你会退回到上一个岔路口,并在纸上擦掉最后的记录。

现在,我们按照这个思路来解释代码的执行过程: 开始探索:你从迷宫的入口(根节点)开始,手里的纸是空的。

记录每一步:每向前走一步,就在纸上记录下当前的位置(每深入一层递归,就把当前节点的值加到path列表中)。

检查是否找到宝藏:每当你到达一个死路(叶子节点),你检查一下手里的纸(当前路径)上记录的所有步骤加起来是否等于宝藏的位置(targetSum)。如果是,你就把这张纸的副本(一条成功的路径)留在宝藏箱里(加入到result列表中)。

回退到上一个岔路口:不管这条路是否成功,每当探索完一条路径后,你都会回到上一个岔路口准备探索另一条路。这时,你就会在纸上擦掉最后的记录(执行path.pop()),因为你要撤销最后的这一步,回到之前的状态。

继续探索:回到岔路口后,如果还有没走过的路,你就按照同样的方式继续探索,直到探索完所有可能的路径。

101. 对称二叉树

最先想到的是利用层序遍历的思想,比较每一层是否对称,但是一看就不行。

正确的思路:同时递归遍历左子树和右子树,比较镜像节点。如果所有节点都满足条件,则就是对称的。

python 复制代码
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def isSymmetric(root: TreeNode) -> bool:
    if not root:
        return True
    
    def isMirror(left: TreeNode, right: TreeNode) -> bool:
        if not left and not right:
            return True
        if not left or not right or left.val != right.val:
            return False
        
        return isMirror(left.left, right.right) and isMirror(left.right, right.left)
    
    return isMirror(root.left, root.right)

ai理解:

让我们一步一步梳理isMirror函数的逻辑,这个函数用于检查两个树节点是否是镜像对称的:

  1. 基本情况

    • 如果两个节点都为空 ,说明我们到达了树的末端,而且这一部分是对称的。因此,返回True
    • 如果一个节点为空而另一个不为空 ,或者两个节点都不为空但值不相等 ,说明这一部分不对称。因此,返回False
  2. 递归逻辑

    • 如果两个节点都不为空,并且它们的值相等,我们继续检查这两个节点的子节点。
      • 我们检查当前节点的左子节点与另一节点的右子节点是否对称(left.leftright.right)。
      • 同时,我们也检查当前节点的右子节点与另一节点的左子节点是否对称(left.rightright.left)。
    • 这个逻辑是基于对称树的性质:如果两个树是对称的,那么一棵树的左子树与另一棵树的右子树镜像对称,同时一棵树的右子树与另一棵树的左子树也镜像对称。
  3. 返回值

    • 我们通过逻辑与操作符(and)连接这两个递归调用的结果。只有当两个子树都是对称的(即left.leftright.right对称,且left.rightright.left对称),我们才认为整体是对称的,返回True
    • 如果任一对子树不对称,整体就不对称,返回False

通过这种方式,isMirror函数能够自顶向下递归地检查二叉树的每一层是否对称。这个过程中,每一次递归调用都是基于对称性的要求,逐步验证整棵树是否满足这一条件。

相关推荐
聚客AI15 小时前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm
大怪v18 小时前
前端:人工智能?我也会啊!来个花活,😎😎😎“自动驾驶”整起!
前端·javascript·算法
惯导马工20 小时前
【论文导读】ORB-SLAM3:An Accurate Open-Source Library for Visual, Visual-Inertial and
深度学习·算法
骑自行车的码农21 小时前
【React用到的一些算法】游标和栈
算法·react.js
博笙困了21 小时前
AcWing学习——双指针算法
c++·算法
moonlifesudo1 天前
322:零钱兑换(三种方法)
算法
NAGNIP2 天前
大模型框架性能优化策略:延迟、吞吐量与成本权衡
算法
美团技术团队2 天前
LongCat-Flash:如何使用 SGLang 部署美团 Agentic 模型
人工智能·算法
Fanxt_Ja2 天前
【LeetCode】算法详解#15 ---环形链表II
数据结构·算法·leetcode·链表
侃侃_天下2 天前
最终的信号类
开发语言·c++·算法