LeetCode Problems #797

图遍历算法解析
本文详细解析了在有向无环图中寻找所有从源节点到目标节点路径的图遍历算法,通过递归实现,并提供了防止死循环的改进算法。

2018年9月30日

#797. All Paths From Source to Target

问题描述:

Given a directed, acyclic graph of N nodes.  Find all possible paths from node 0 to node N-1, and return them in any order.

The graph is given as follows:  the nodes are 0, 1, ..., graph.length - 1.  graph[i] is a list of all nodes j for which the edge (i, j) exists.

样例:

Example:
Input: [[1,2], [3], [3], []] 
Output: [[0,1,3],[0,2,3]] 
Explanation: The graph looks like this:
0--->1
|    |
v    v
2--->3
There are two paths: 0 -> 1 -> 3 and 0 -> 2 -> 3.

Note:

  • The number of nodes in the graph will be in the range [2, 15].
  • You can print different paths in any order, but you should keep the order of nodes inside one path.

问题分析:

本题难度为Medium!已给出的函数定义为:

class Solution:
    def allPathsSourceTarget(self, graph):
        """
        :type graph: List[List[int]]
        :rtype: List[List[int]]
        """

其中graph为一个二维数组,返回值为一个存储列表单元的列表;

本题是找出从源结点0到目标结点N-1的所有路径。

 

算法如下:

从源结点0出发,记录到path列表中,即path=[0]

调用递归函数dfs,cur=0,des=N-1,path=[0]

        若cur==des,则将path添加到result中

        否则若cur有出度,对于每一个出度结点each:

                复制路径cp_path=path,将每一个出度结点添加到复制的路径中

                 调用递归函数dfs,cur=each,des=N-1,cp_path

result即为存储的所有路径

 

代码实现:

#coding=utf-8
class Solution:
    def allPathsSourceTarget(self, graph):
        """
        :type graph: List[List[int]]
        :rtype: List[List[int]]
        """
        def dfs(cur, des, path):
            if cur==des: #到达目标点
                result.append(path)
            elif len(graph[cur])!=0: #未到达目标点,且cur点出度不为0,进行递归
                for each in graph[cur]: #对每个出度进行递归
                    cp_path=path.copy() #复制临时路径
                    cp_path.append(each)
                    dfs(each,des,cp_path)
        result=[]
        dfs(0,len(graph)-1,[0])
        return result

此算法可以在Leetcode上Accrpted,但只能处理有向无环图dag;若遇到有向有环图,则会陷入死循环导致:RecursionError: maximum recursion depth exceeded in comparison。

 

改进算法代码如下:

添加一个visited列表记录访问过的结点,从而防止递归陷入死循环。

#coding=utf-8
class Solution:
    def allPathsSourceTarget(self, graph):
        """
        :type graph: List[List[int]]
        :rtype: List[List[int]]
        """
        def dfs(cur, des, path, visited):
            if cur==des: #到达目标点
                result.append(path)
            elif len(graph[cur])!=0: #未到达目标点,且cur点出度不为0,进行递归
                for each in graph[cur]: #对每个出度进行递归
                    if visited[each]==0:
                        cp_path=path.copy() #复制临时路径
                        cp_path.append(each) #添加结点
                        cp_visited=visited.copy() #复制临时访问列表
                        cp_visited[each]=1 #标记结点
                        dfs(each,des,cp_path,cp_visited)
        result=[]
        visited=[0 for i in range(len(graph))]
        visited[0]=1
        dfs(0,len(graph)-1,[0],visited)
        return result

 

<think>好的,我现在需要帮助用户找到LeetCode中的第1题和第3题的链接,并确认它们属于哪个题库。首先,用户之前询问了关于转岗开发的学习计划,其中提到了LeetCode的题目编号,现在用户想知道这些题目的具体链接和所属题库。 首先,我需要回忆LeetCode的题目编号系统。LeetCode的题目是按照提交时间顺序编号的,所以题号是连续的。第1题通常是Two Sum,第3题是Longest Substring Without Repeating Characters。不过,用户可能会混淆不同的题库,比如中文版的力扣(LeetCode China)是否有不同的编号,但通常国际版和中文版的题目编号是一致的,只是标题翻译成中文。 接下来,我需要确认用户提到的题目是否确实是这两个。根据常见的LeetCode高频题目,这两个题号对应的题目是正确的。所以需要给出对应的链接。国际版和中文版的链接不同,用户可能在使用中文版,所以需要同时提供两种链接,或者询问用户是否需要中文版的链接。不过根据用户的工作背景,可能更倾向于国际版,但为了全面,应该都提供。 另外,用户可能不太清楚题目的具体内容,需要简要描述题目内容,以便用户理解为什么要刷这些题。例如,Two Sum是数组和哈希表的应用,而第三题涉及滑动窗口或双指针技巧,这些在车机开发中处理数据或算法时可能会用到。 还需要检查链接是否正确,避免给出错误的链接。例如,国际版的第1题链接是https://leetcode.com/problems/two-sum/,而中文版的是https://leetcode.cn/problems/two-sum/。同样的,第三题的国际版链接是https://leetcode.com/problems/longest-substring-without-repeating-characters/,中文版是https://leetcode.cn/problems/longest-substring-without-repeating-characters/。 另外,用户可能想知道这些题目属于哪个分类,比如数组、哈希表、字符串等,这样他们可以更有针对性地练习。例如,Two Sum属于数组和哈希表,第三题属于字符串和滑动窗口。 最后,需要确保回答清晰,结构合理,使用用户容易理解的语言,避免技术术语过多,同时保持专业性。可能需要用列表或格式化的方式呈现信息,让用户一目了然。 总结一下,回答需要包含以下几点: 1. 题目编号对应的题目名称。 2. 题目所属的LeetCode题库(国际版和中文版)。 3. 每个题目的简要描述和考察重点。 4. 对应的链接。 5. 解释为什么选择这些题目,与用户的学习计划相关。 现在需要将这些信息组织成自然的中文回答,确保准确性和有用性。</think>以下是LeetCode相关题目的详细信息整理: --- ### **LeetCode题目定位说明** #### **1. LeetCode #1** - **国际版标题**:`Two Sum` - **中文版标题**:`两数之和` - **所属分类**:数组 + 哈希表 - **题目链接**: - 国际版:https://leetcode.com/problems/two-sum/ - 中文版:https://leetcode.cn/problems/two-sum/ - **考察重点**: - 利用哈希表实现$O(n)$时间复杂度 - 数据索引与值的关系映射(车机开发中常用于状态快速查询) #### **2. LeetCode #3** - **国际版标题**:`Longest Substring Without Repeating Characters` - **中文版标题**:`无重复字符的最长子串` - **所属分类**:滑动窗口 + 字符串 - **题目链接**: - 国际版:https://leetcode.com/problems/longest-substring-without-repeating-characters/ - 中文版:https://leetcode.cn/problems/longest-substring-without-repeating-characters/ - **考察重点**: - 滑动窗口算法(车机轨迹线动态规划中常用类似思想) - 边界条件处理(与实时系统开发中的异常场景处理高度相关) --- ### **为什么选择这两题?** 1. **高频面试题**:90%以上车企/Tier1开发岗必考题型 2. **技能迁移性**: - `Two Sum` → 车机传感器数据匹配(如雷达点云快速索引) - `最长子串` → 视图系统事件流分析(如触控手势连续性判断) --- ### **题库版本说明** - **国际版**:题目更新更快,社区讨论更活跃(推荐优先使用) - **中文版**:题目描述为中文,适合英语阅读有障碍时参考 --- ### **下一步建议** ```mermaid graph TD A[完成题目] --> B[提交通过] B --> C{是否理解最优解?} C -->|是| D[尝试用C++11特性重构] C -->|否| E[参考官方题解] D --> F[关联Effective C++条款] F --> G[例如Item3: const优化变量声明] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值