力扣每日练习(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函数能够自顶向下递归地检查二叉树的每一层是否对称。这个过程中,每一次递归调用都是基于对称性的要求,逐步验证整棵树是否满足这一条件。

相关推荐
算AI14 小时前
人工智能+牙科:临床应用中的几个问题
人工智能·算法
hyshhhh16 小时前
【算法岗面试题】深度学习中如何防止过拟合?
网络·人工智能·深度学习·神经网络·算法·计算机视觉
杉之17 小时前
选择排序笔记
java·算法·排序算法
Naive_717 小时前
蓝桥杯准备(前缀和差分)
java·职场和发展·蓝桥杯
烂蜻蜓17 小时前
C 语言中的递归:概念、应用与实例解析
c语言·数据结构·算法
OYangxf17 小时前
图论----拓扑排序
算法·图论
我要昵称干什么17 小时前
基于S函数的simulink仿真
人工智能·算法
AndrewHZ18 小时前
【图像处理基石】什么是tone mapping?
图像处理·人工智能·算法·计算机视觉·hdr
念九_ysl18 小时前
基数排序算法解析与TypeScript实现
前端·算法·typescript·排序算法
守正出琦18 小时前
日期类的实现
数据结构·c++·算法