[LeetCode] 797. All Paths From Source to Target

本文介绍了一个基于DFS递归算法的问题解决方法,旨在寻找有向无环图中从起点到终点的所有可能路径。通过实例演示了如何实现递归过程,并解释了关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题链接: https://leetcode.com/problems/all-paths-from-source-to-target/

1. 题目介绍

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.

给出一个有向无环图,图中共有 N 个节点。找出所有从零开始,到达 N-1 的路径。返回这些路径。可以把这些路径以任意顺序返回,但是路径内的节点顺序必须正确。

这个有向无环图如下:这些节点是0、1、······、graph.lenght-1 .
graph[ i ]中的值,是从 节点 i 出发,能到达的所有节点的标号。 如果 graph[ i ]为空,那就是没有下一个结点了。

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.
图中节点的个数范围是[2, 15].
可以把这些路径以任意顺序返回,但是路径内的节点顺序必须正确。

2. 解题思路-DFS递归求解

这道题是利用DFS + 递归解决的。需要说明的是,递归只是一种实现方式,和DFS、动态规划并不矛盾。很多题也可以使用动态规划 + 递归的组合方式解决(也就是记忆数组+递归)。

DFS 就是从一开始的节点出发,搜索每个节点能到达的所有点。
搜索某一个节点时,首先要把这个节点添加到路径里面去。如果这个点就是终点,那么就把那条路径记录下来,放到结果的Arraylist里面去;如果不是终点,那就继续搜这个点能去的其他点。 无论是否能到达终点,最终搜索完成后,一定要把这个节点从路径中删除。

实现代码

class Solution {
    public List<List<Integer>> allPathsSourceTarget(int[][] graph) {
		List<List<Integer>> ans = new ArrayList<>();
		recursion( ans , 0, new ArrayList<Integer>() , graph);
		return ans;
    }
	
	public void recursion(List<List<Integer>> ans , int curNode , List<Integer> path , int[][] graph ) {
		path.add(curNode);
		if( curNode == graph.length - 1) {
			//如果是最后的节点,就放入path中
			ans.add(new ArrayList<>(path));
			
			/* 上面这一行代码不能是 ans.add(path);
			 * ans.add(path);是直接把path加进ans总结果中,
			 * ans.add(new ArrayList<>(path)); 则是把一个和path相同的ArrayList放进去,
			 * path本身并没有被放入ans。后面还要用同一个path去找其他的路径呢。
			 * 比如题目中给出来的例子,当找到0 1 3这一正确的路径后
			 * 后面找其他的路径时必然会改动path,如果path被放入ans,那么ans也被一起改了。
			 * 所以path要接着用,只需要放一个复制品到ans里面就行了
			*/
		}else {
			//遍历这个节点所有可以到达的点
			for(int  i = 0 ; i < graph[curNode].length ; i++) {
				recursion( ans , graph[curNode][i] , path , graph);
			} 
		}
		//每次递归结束都要从path中移去当前的节点。这一条语句和语句path.add(curNode)相对应
		path.remove(path.size() - 1);
		return;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值