LeetCode题目113:多种算法实现 路径总和ll

简介: LeetCode题目113:多种算法实现 路径总和ll

作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。

会一些的技术:数据分析、算法、SQL、大数据相关、python

欢迎加入社区:码上找工作

作者专栏每日更新:

LeetCode解锁1000题: 打怪升级之旅

python数据分析可视化:企业实战案例

python源码解读

程序员必备的数学知识与应用

题目描述

给你一个二叉树和一个目标和 targetSum,找出所有从根节点到叶子节点路径总和等于给定目标和的路径。

示例

示例

输入:

5
   / \
  4   8
 /   / \
11  13  4
/ \      / \
7   2    5   1

目标和 targetSum = 22

输出:[[5,4,11,2], [5,8,4,5]]

方法一:递归深度优先搜索(DFS)

解题步骤
  1. 递归函数定义:定义一个辅助函数来递归检查每个节点,传递当前路径和累积路径列表。
  2. 递归终止条件:如果当前节点是叶子节点,并且其值加上累计总和等于目标值,将路径添加到结果列表。
  3. 递归逻辑:递归检查当前节点的左右子节点,并更新路径列表和当前和。
Python 示例
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
def pathSum(root, targetSum):
    results = []
    
    def dfs(node, current_sum, path):
        if not node:
            return
        current_sum += node.val
        path.append(node.val)
        
        if not node.left and not node.right and current_sum == targetSum:
            results.append(path.copy())  # 注意复制列表
        
        dfs(node.left, current_sum, path)
        dfs(node.right, current_sum, path)
        path.pop()  # 回溯
    
    dfs(root, 0, [])
    return results
算法分析
  • 时间复杂度:(O(n)),每个节点访问一次。
  • 空间复杂度:(O(h)),递归栈的深度,其中 (h) 是树的高度。

方法一使用递归的深度优先搜索(DFS)来寻找所有符合条件的路径。虽然这种方法直观且能有效地解决问题,但它可能会因为大量的递归调用而在空间复杂度上较高,特别是在不平衡的树中。以下是对方法一的几项改进,旨在优化其性能和可读性。

方法一改进:优化的递归DFS

改进点
  1. 短路逻辑:一旦达到一个叶子节点并且路径和不符合目标值,立即回溯,减少不必要的递归。
  2. 减少中间数组操作:通过直接传递路径而不是在每次递归中创建新的数组拷贝,可以减少内存的使用和可能的垃圾回收。
改进后的 Python 示例
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
def pathSum(root, targetSum):
    results = []
    
    def dfs(node, current_sum, path):
        if not node:
            return
        
        # 更新当前路径和
        current_sum += node.val
        # 将当前节点值添加到路径中
        path.append(node.val)
        
        # 检查当前节点是否为叶子节点且路径和是否符合条件
        if not node.left and not node.right:
            if current_sum == targetSum:
                results.append(list(path))  # 添加一份路径的拷贝
        
        # 递归遍历左右子节点
        if node.left:
            dfs(node.left, current_sum, path)
        if node.right:
            dfs(node.right, current_sum, path)
        
        # 回溯,移除当前节点值
        path.pop()
    dfs(root, 0, [])
    return results
算法分析
  • 时间复杂度:优化后,时间复杂度仍为 (O(n)),因为每个节点最多被访问一次。
  • 空间复杂度:优化后的空间复杂度主要取决于递归的深度,最坏情况下为 (O(h)),其中 (h) 是树的高度。使用回溯法避免了不必要的数组拷贝,减少了内存占用。
优劣势比较
  • 优点
  • 减少内存占用,尤其是通过避免不必要的数组拷贝。
  • 短路逻辑减少了无效的路径探索,提高了算法效率。
  • 缺点
  • 代码复杂度略有增加,需要仔细管理路径变量和回溯机制。

通过这种改进,递归方法在处理复杂或深度较大的树结构时变得更加高效和稳健。这种优化使得方法既能快速找到解决方案,又能控制内存的使用,适合在资源受限的环境中运行。

方法二:迭代使用栈

解题步骤
  1. 使用栈:利用栈存储每个节点及其对应的路径总和和当前路径。
  2. 迭代逻辑:迭代访问每个节点,更新路径总和,检查叶子节点的路径总和。
Python 示例
def pathSum(root, targetSum):
    if not root:
        return []
    results = []
    stack = [(root, root.val, [root.val])]
    
    while stack:
        node, curr_sum, path = stack.pop()
        if not node.left and not node.right and curr_sum == targetSum:
            results.append(path)
        if node.right:
            stack.append((node.right, curr_sum + node.right.val, path + [node.right.val]))
        if node.left:
            stack.append((node.left, curr_sum + node.left.val, path + [node.left.val]))
    
    return results
算法分析
  • 时间复杂度:(O(n)),每个节点至多访问一次。
  • 空间复杂度:(O(n)),在最坏的情况下,栈中需要存储所有节点。

优劣势对比

方法 优点 缺点
DFS递归 代码直观易懂;适合复杂树结构 高空间复杂度,依赖于树的高度
迭代使用栈 明确控制遍历过程;适合避免递归引起的问题 空间复杂度较高,代码复杂度高于递归

应用示例

这些方法广泛应用于计算机科学的多个领域,尤其是在路径和网络流中,路径总和问题可用于决策支持系统、资源管理和网络数据传输路径优化等方面。


欢迎关注微信公众号 数据分析螺丝钉

相关文章
|
7天前
|
算法 Java
[Java·算法·简单] LeetCode 283. 移动零
[Java·算法·简单] LeetCode 283. 移动零
16 2
|
7天前
|
算法 Java
[Java·算法·中等] LeetCode21. 合并两个有序链表
[Java·算法·中等] LeetCode21. 合并两个有序链表
13 2
|
10天前
|
存储 算法 调度
力扣中级算法(Python)
力扣中级算法(Python)
|
9天前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-2
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
9天前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-1
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
10天前
|
算法 Python
力扣初级算法(Python)(二)
力扣初级算法(Python)(二)
|
10天前
|
算法 Python
力扣初级算法(Python)(一)
力扣初级算法(Python)(一)
|
3天前
|
人工智能 算法 搜索推荐
蓝桥杯宝藏排序题目算法(冒泡、选择、插入)
以下是内容的摘要: 本文介绍了三种排序算法:冒泡排序、选择排序和插入排序。冒泡排序通过不断交换相邻的逆序元素逐步排序,最坏情况下需要 O(n^2) 次比较。选择排序在每轮中找到剩余部分的最小元素并放到已排序序列的末尾,同样具有 O(n^2) 时间复杂度。插入排序则是将每个元素插入到已排序序列的正确位置,时间复杂度也是 O(n^2),但空间复杂度为 O(1)。
|
11天前
|
容器
【LeetCode刷题】栈和队列题目练习~
【LeetCode刷题】栈和队列题目练习~
【42页动态规划学习笔记分享】动态规划核心原理详解及27道LeetCode相关经典题目汇总(4)
【42页动态规划学习笔记分享】动态规划核心原理详解及27道LeetCode相关经典题目汇总