LeetCode 之 #113 路径总和 II,详解每一步
2023-11-04 22:45:17
导语
LeetCode 作为程序员修炼场,汇聚了无数经典的算法难题,如「路径总和 II」这一题,考验我们运用递归,在二叉树中找到符合指定和的路径。本文将结合 LeetCode 社区顾毅大师的 Swift 题解,为你深度解析这一算法,让你步步为营,掌握解题之道。
算法阐述
「路径总和 II」要求我们在给定一个二叉树和一个目标和的情况下,找出所有从根节点到叶节点的路径,使得这些路径上节点的值之和等于目标和。
顾名思义,递归是解决此类问题的利器。我们可以从根节点出发,以递归的方式遍历二叉树,并记录当前路径上的节点值之和。当我们到达叶节点时,检查当前和是否等于目标和,若相等,则将该路径保存下来。
Swift 解法
func pathSum(_ root: TreeNode?, _ targetSum: Int) -> [[Int]] {
var result: [[Int]] = []
pathSum(root, targetSum, [], &result)
return result
}
func pathSum(_ root: TreeNode?, _ targetSum: Int, _ path: [Int], _ result: inout [[Int]]) {
guard let root = root else { return }
var path = path
path.append(root.val)
if root.left == nil && root.right == nil {
if targetSum == root.val {
result.append(path)
}
return
}
pathSum(root.left, targetSum - root.val, path, &result)
pathSum(root.right, targetSum - root.val, path, &result)
}
算法剖析
步骤 1: 初始化一个空列表 result
来存储符合条件的路径。
步骤 2: 调用递归函数 pathSum
,从根节点出发,目标和为 targetSum
,路径为空列表 []
,以及结果列表 result
的引用。
步骤 3: 在 pathSum
函数中,当根节点为 nil
时,直接返回,因为无路可走。
步骤 4: 将当前根节点的值添加到路径 path
中。
步骤 5: 判断当前节点是否为叶节点(左右子节点均为 nil
)。如果是叶节点,则检查当前路径和是否等于目标和。如果相等,则将 path
添加到 result
中。
步骤 6: 如果当前节点不是叶节点,则继续递归遍历其左右子节点,并将目标和减去当前根节点的值,同时将更新后的路径 path
传递下去。
算法优化
LeetCode 中算法的效率也是衡量标准之一。本文提供的 Swift 解法基于递归实现,时间复杂度为 O(N),空间复杂度为 O(H),其中 N 为二叉树节点总数,H 为二叉树高度。
为了优化效率,可以采用以下技巧:
- 备忘录法: 在递归过程中,将计算过的结果保存起来,避免重复计算。
- 后序遍历: 从叶节点开始向上遍历,这样在遇到叶节点时,路径和已经计算完成,不需要回溯。
结语
通过对 LeetCode「路径总和 II」算法的深入剖析,我们不仅掌握了这道经典算法题的解法,还对递归在算法中的应用有了更深刻的理解。算法之路任重道远,愿每一位程序员都能通过 LeetCode 的磨砺,精进技艺,成为算法高手!