Leetcode0797. 所有可能的路径(medium, DFS)
1. 题目描述
给你一个有 n
个节点的 有向无环图(DAG),请你找出所有从节点 0
到节点 n-1
的路径并输出(不要求按特定顺序)
graph[i]
是一个从节点 i
可以访问的所有节点的列表(即从节点 i
到节点 graph[i][j]
存在一条有向边)。
示例 1:
输入:graph = [[1,2],[3],[3],[]] 输出:[[0,1,3],[0,2,3]] 解释:有两条路径 0 -> 1 -> 3 和 0 -> 2 -> 3
示例 2:
输入:graph = [[4,3,1],[3,2,4],[3],[4],[]] 输出:[[0,4],[0,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,4]]
提示:
n == graph.length
2 <= n <= 15
0 <= graph[i][j] < n
graph[i][j] != i
(即不存在自环)graph[i]
中的所有元素 互不相同- 保证输入为 有向无环图(DAG)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/all-paths-from-source-to-target
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2. 解题分析
第一感是可达性(reachability)问题,可以用深度优先搜索。
但是题目并不是只是要求判断可达性,而是要找出所有的路径,所以可以看作是路径遍历搜索问题。仍然可以用深度优先搜索来处理,但是不是已找到目标点就结束,而是必须遍历完整个图找出所有可能路径。在搜索过程中必须记忆并最终输出所有路径。
但是在代码实现方面有一些小的细节需要注意。参见后面的描述。
3. 一个代码问题:TypeError: 'NoneType' object is not subscriptable
在代码实现中碰到一个问题,报错信息为'NoneType' object is not subscriptable。
原始代码如下:
class Solution:
def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]:
paths = []
N = len(graph)
print(N, graph)
def dfs(path):
nonlocal paths
nonlocal N
nonlocal graph
print('dfs(): ', path, graph)
# Traverse all neighbor nodes of the last node except those already in path
for node in graph[path[-1]]:
print('dfs(): ', path, graph[path[-1]], node)
if node == N-1:
# One path found
paths.append(path.append(node))
else:
if node not in path:
dfs(path.append(node))
dfs([0])
return paths
if __name__ == '__main__':
sln = Solution()
graph = [[1,2],[3],[3],[]]
print(sln.allPathsSourceTarget(graph))
graph = [[4,3,1],[3,2,4],[3],[4],[]]
print(sln.allPathsSourceTarget(graph))
看打印信息,百思不得其解。。。 最后终于明白了。伙伴们,你看出来了吗?
有兴趣的小伙伴可以先看看能不能找出以上代码中的错误并订正,然后再看下面的正确解答。
4. 代码实现
class Solution:
def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]:
paths = []
N = len(graph)
print(N, graph)
def dfs(path):
nonlocal paths
nonlocal N
nonlocal graph
# print('dfs(): ', path, graph)
# Traverse all neighbor nodes of the last node except those already in path
for node in graph[path[-1]]:
if node == N-1:
# One path found
paths.append(path+[node])
else:
if node not in path:
dfs(path+[node])
dfs([0])
return paths
if __name__ == '__main__':
sln = Solution()
graph = [[1,2],[3],[3],[]]
print(sln.allPathsSourceTarget(graph))
graph = [[4,3,1],[3,2,4],[3],[4],[]]
print(sln.allPathsSourceTarget(graph))
执行用时:48 ms, 在所有 Python3 提交中击败了53.25%的用户
内存消耗:16.3 MB, 在所有 Python3 提交中击败了34.41%的用户
回到主目录:笨牛慢耕的Leetcode解题笔记(动态更新。。。)
相关文章
- sql查询数据库中所有表名_使用权和所有权的区别
- leetcode刷题(128)——1575. 统计所有可行路径,动态规划解法
- MySQL数据库的权限控制实践(mysql赋予所有权限)
- Oracle: 为所有表授予权限(oracle所有表授权)
- 开放式Linux软件仓库:满足您的所有需求(linux软件仓库)
- 查看MySQL所有用户的快捷方法(查看mysql的所有用户)
- 网联明年6月全面上线,央行要求所有网络支付通过网联
- Oracle数据库中关闭所有约束的方法(oracle关闭所有约束)
- tablesOracle中所有表的汇总AllTables(oracle中的all)
- java用递归获取一个目录下的所有文件路径的小例子
- 递归删除一个节点以及该节点下的所有节点示例
- php遍历文件夹下的所有文件和子文件夹示例
- java正则表达式匹配网页所有网址和链接文字的示例
- PHP清除数组中所有字符串两端空格的方法
- C语言实现找出二叉树中某个值的所有路径的方法