返回

陪你刷题不孤单:从一文搞定路径总和(Path Sum)与路径总和 ii(Path Sum ii)难题开始

后端

披荆斩棘,二叉树难题进击指南

算法和数据结构的世界里,二叉树扮演着不可或缺的角色。它们以高效的存储方式和广泛的应用场景,成为解决众多复杂问题的利器。然而,当我们面对二叉树相关的难题时,也会难免感到畏惧。毕竟,算法需要扎实的基础和灵活的思维,才能从中找到通往胜利的捷径。

狭路相逢,勇闯路径总和迷宫

路径总和(Path Sum)难题是二叉树难题中的常见拦路虎。它要求我们在给定的二叉树中,寻找是否存在一条从根节点到叶节点的路径,使得这条路径上所有节点的值之和等于给定的目标值。乍一看,这似乎是个死胡同,但只要我们耐心分析,就不难发现解决问题的关键在于使用深度优先搜索(DFS)算法。

DFS 算法就像一个勇敢的探险家,它不畏艰险,深入二叉树的每一个角落,寻找通往目标的路径。当探险家遍历到某个节点时,它会将该节点的值加到当前路径的总和中。如果到达叶节点时,路径总和恰好等于目标值,那么我们就找到了我们要找的路径。

勇往直前,路径总和 ii 绝地反击

征服了路径总和的挑战后,我们继续前进,来到路径总和 ii(Path Sum ii)难题。这次,问题变得更加复杂:我们需要找到二叉树中所有从根节点到叶节点的路径,使得每条路径上的节点值之和都等于给定的目标值。这一次,我们需要借助递归算法的力量。

递归算法就像一个无所畏惧的骑士,它一次又一次地重复相同的步骤,直到找到最终的答案。在路径总和 ii 问题中,递归算法会不断地将当前节点的值添加到路径总和中,然后分别递归地探索该节点的左右子树。当到达叶节点时,如果路径总和等于目标值,那么我们就找到了我们要找的路径。

不负初心,代码实现一览无余

为了帮助你更好地理解这些算法的具体实现,我们提供了详细的代码示例。你可以通过这些代码,亲手实践算法的运作过程,并加深对问题的理解。

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        if not root:
            return False

        stack = [(root, root.val)]
        while stack:
            node, curr_sum = stack.pop()
            if not node.left and not node.right:
                if curr_sum == targetSum:
                    return True
            else:
                if node.left:
                    stack.append((node.left, curr_sum + node.left.val))
                if node.right:
                    stack.append((node.right, curr_sum + node.right.val))

        return False

    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
        if not root:
            return []

        res = []

        def dfs(node, curr_sum, path):
            if not node:
                return

            curr_sum += node.val
            path.append(node.val)

            if not node.left and not node.right:
                if curr_sum == targetSum:
                    res.append(path[:])
            else:
                dfs(node.left, curr_sum, path)
                dfs(node.right, curr_sum, path)

            path.pop()

        dfs(root, 0, [])

        return res

拨开云雾,重见柳暗花明

通过对路径总和与路径总和 ii 难题的深入探讨,我们不仅学习了如何解决这些问题,更重要的是,我们对二叉树的理解也更加深入。我们领略了 DFS 与递归算法的强大魅力,也对深度优先搜索的思想有了更深刻的认识。

下次当你遇到与二叉树相关的难题时,不要退缩,也不要气馁。勇敢地迎难而上,用你手中的利器去劈开迷雾,找寻那柳暗花明的出路。算法的世界,没有捷径,只有不懈的努力和永不言败的精神。你准备好接受挑战了吗?

常见问题解答

  • 路径总和和路径总和 ii 的主要区别是什么?

路径总和要求我们找到是否存在一条从根节点到叶节点的路径,使得路径上的节点值之和等于目标值。而路径总和 ii 则要求我们找到所有满足这一条件的路径。

  • DFS 和递归算法在解决路径总和问题中的作用是什么?

DFS 算法是一种深度优先搜索算法,它通过不断深入树的各个分支来寻找目标路径。递归算法则通过重复地调用自身,来探索树中的不同分支。

  • 代码示例中使用的 stack 和 path 变量有什么作用?

stack 变量用于存储当前正在探索的节点和路径总和。path 变量则用于存储当前路径上的节点值。

  • 如何知道我已经找到了所有满足条件的路径?

在递归算法中,当我们到达叶节点时,如果路径总和等于目标值,那么我们就找到了一个满足条件的路径。

  • 二叉树中还有哪些其他常见的难题?

除了路径总和和路径总和 ii 之外,二叉树中还有许多其他常见的难题,例如二叉树最大深度、二叉树最小深度、二叉树平衡检查、二叉树镜像、二叉树层次遍历等。