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

相关推荐
Kalika0-040 分钟前
猴子吃桃-C语言
c语言·开发语言·数据结构·算法
sp_fyf_20241 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-02
人工智能·神经网络·算法·计算机视觉·语言模型·自然语言处理·数据挖掘
我是哈哈hh3 小时前
专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结
服务器·数据结构·c++·算法·机器学习·深度优先·剪枝
Tisfy3 小时前
LeetCode 2187.完成旅途的最少时间:二分查找
算法·leetcode·二分查找·题解·二分
Mephisto.java3 小时前
【力扣 | SQL题 | 每日四题】力扣2082, 2084, 2072, 2112, 180
sql·算法·leetcode
robin_suli3 小时前
滑动窗口->dd爱框框
算法
丶Darling.3 小时前
LeetCode Hot100 | Day1 | 二叉树:二叉树的直径
数据结构·c++·学习·算法·leetcode·二叉树
labuladuo5203 小时前
Codeforces Round 977 (Div. 2) C2 Adjust The Presentation (Hard Version)(思维,set)
数据结构·c++·算法
jiyisuifeng19914 小时前
代码随想录训练营第54天|单调栈+双指针
数据结构·算法
꧁༺❀氯ྀൢ躅ྀൢ❀༻꧂4 小时前
实验4 循环结构
c语言·算法·基础题