返回
巅峰博弈,智取路径:LeetCode题112路径总和的深入剖析
前端
2024-02-11 05:28:33
路飞带你领略算法挑战:LeetCode题112路径总和
一、题目剖析:
LeetCode题112路径总和的题目如下:
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
二、解决方案构建:
破解LeetCode题112路径总和的难题,我们可以采用深度优先搜索(DFS)算法。DFS算法以递归的方式遍历二叉树,从根节点出发,依次访问其子节点,直到遇到叶子节点。在这个过程中,我们需要不断累加路径上的节点值,并与目标和进行比较,一旦路径和等于目标和,就说明找到了满足要求的路径。
1. 递归函数定义:
def hasPathSum(root, targetSum):
# 如果根节点为空,直接返回False
if root is None:
return False
# 如果当前节点是叶子节点,并且路径和等于目标和,则返回True
if root.left is None and root.right is None and root.val == targetSum:
return True
# 递归遍历左子树和右子树,并检查是否存在满足要求的路径
left_path_exists = hasPathSum(root.left, targetSum - root.val)
right_path_exists = hasPathSum(root.right, targetSum - root.val)
# 如果左子树或右子树存在满足要求的路径,则返回True
return left_path_exists or right_path_exists
2. 算法流程解析:
- 首先,我们判断根节点是否为空,若为空,直接返回False,因为空树不包含任何路径。
- 其次,我们检查当前节点是否是叶子节点,即其左子树和右子树都为空。如果是叶子节点,并且路径和等于目标和,则说明找到了满足要求的路径,返回True。
- 接下来,我们分别递归遍历左子树和右子树,并将当前节点的值从目标和中减去,得到新的目标和。
- 最后,我们检查左子树或右子树是否存在满足要求的路径,即是否存在从根节点到叶子节点的路径,使得路径和等于目标和。如果存在,则返回True;否则,返回False。
三、代码实现:
# 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
def hasPathSum(root, targetSum):
# 如果根节点为空,直接返回False
if root is None:
return False
# 如果当前节点是叶子节点,并且路径和等于目标和,则返回True
if root.left is None and root.right is None and root.val == targetSum:
return True
# 递归遍历左子树和右子树,并检查是否存在满足要求的路径
left_path_exists = hasPathSum(root.left, targetSum - root.val)
right_path_exists = hasPathSum(root.right, targetSum - root.val)
# 如果左子树或右子树存在满足要求的路径,则返回True
return left_path_exists or right_path_exists
四、复杂度分析:
- 时间复杂度:O(n),其中n为二叉树的节点数。DFS算法需要遍历二叉树中的所有节点,因此时间复杂度为O(n)。
- 空间复杂度:O(n),DFS算法在递归过程中需要使用栈来存储当前遍历的节点,最坏情况下栈中可能包含从根节点到叶子节点的所有节点,因此空间复杂度为O(n)。
五、扩展思考:
- LeetCode题112路径总和的变体:如果要求路径上的节点值可以重复使用,该如何修改算法?
- 如果要求路径上的节点值必须唯一,该如何修改算法?
- 如果要求路径上的节点值必须按照某种顺序排列,该如何修改算法?