leetcode 797所有可能的路径

797.所有可能的路径
这个是一个典型的求路径的题(图论),也是递归方法/层序方法的实际应用,也就是我们常说的DFS和BFS在实际问题中的应用
给你一个有 n 个节点的 有向无环图(DAG),请你找出从节点 0 到节点 n-1 的所有路径并输出(不要求按特定顺序)

graph[i] 是一个从节点 i 可以访问的所有节点的列表(即从节点 i 到节点 graph[i][j]存在一条有向边)。

在这里插入图片描述

输入:graph = [[1,2],[3],[3],[]]
输出:[[0,1,3],[0,2,3]]
解释:有两条路径 0 -> 1 -> 3 和 0 -> 2 -> 3

在这里插入图片描述
输入: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]]

有向无权图dfs搜索过程.需要用到回溯

class Solution:
    def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]:
    		result = []
    		current_path = []
    		target = len(graph) - 1 # 一定要先定好目标是什么
    		def dfs(current_node, current_path):
    			if (current_node == target):
    				result.append(current_path)
    				return
    			for neighbor in graph[current_node]:
    				current_path.append(neighbor)
    				dfs(neighbor, current_path)
    				current_path.pop()
    		
			dfs(0, [0])
			return result

咋一看好像没啥问题,但是其实答案永远都是输出0,这是为什么呢,因为对于result.append(curren_path)来说,存入的是current_path的引用,此时如果current_path变化,result也就会跟着变化,所以需要注意,我们再使用append装数组的时候,需要通过copy来存储副本:

result.append(current_path.copy()]

最终的解答为

class Solution:
    def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]:
    		result = []
    		current_path = []
    		target = len(graph) - 1 # 一定要先定好目标是什么
    		def dfs(current_node, current_path):
    			if (current_node == target):
    				result.append(current_path.copy)
    				return
    			for neighbor in graph[current_node]:
    				current_path.append(neighbor)
    				dfs(neighbor, current_path)
    				current_path.pop()
    		
			dfs(0, [0])
			return result

本质上就是一个二维数组的递归遍历,其实也是DFS的方法.还有一中更加简单的写法

class Solution:
    def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]:
    	self.result = []
    	self.path = []
    	self.target = len(graph)-1

		self.traverse(graph, 0)
		return self.result

	def traverse(self, graph, current_node):
		# 前序
		self.path.append(current_node)
		if current_node == self.target:
			self.result.append(self.path.copy())
			self.path.pop()
			return
		
		for neighbor in graph[current_node]:
			self.traverse(graph, neighbor)
		# 后序
		self.path.pop() # 移除节点s

如果要用BFS,那么可以这样实现

class Solution:
    def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]:
        result = []
        target = len(graph) - 1
        current_path = [0]
        q = deque()
        q.append(current_path)

        while q:
            last_node = current_path[-1]
            current_path = q.popleft()
            if current_path[-1] == target:
                result.append(current_path.copy())
                continue
            for neighbor in graph[last_node]:
                new_path = current_path.copy()
                new_path.append(neighbor)
                q.append(new_path)

        return result
						

这里唯一的注意点就是bfs找路,遍历的过程要用deque记录的是路径而不是节点,所以deque.popleft提取的是一条一条的路,直到这条路满足到达终点的硬性条件.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白云千载尽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值