题目描述
给定一个有 n 个节点的有向无环图,节点编号从 1 到 n。请编写一个函数,找出并返回所有从节点 1 到节点 n 的路径。每条路径应以节点编号的列表形式表示。
输入描述
第一行包含两个整数 N,M,表示图中拥有 N 个节点,M 条边
后续 M 行,每行包含两个整数 s 和 t,表示图中的 s 节点与 t 节点中有一条路径
输出描述
输出所有的可达路径,路径中所有节点之间空格隔开,每条路径独占一行,存在多条路径,路径输出的顺序可任意。如果不存在任何一条路径,则输出 -1。
注意输出的序列中,最后一个节点后面没有空格! 例如正确的答案是 `1 3 5`,而不是 `1 3 5 `, 5后面没有空格!
输入示例
5 5 1 3 3 5 1 2 2 4 4 5
输出示例
1 3 5 1 2 4 5
用例解释:
有五个节点,其中的从 1 到达 5 的路径有两个,分别是 1 -> 3 -> 5 和 1 -> 2 -> 4 -> 5。
因为拥有多条路径,所以输出结果为:
1 3 5
1 2 4 5或
1 2 4 5
1 3 5
都算正确。数据范围:
- 图中不存在自环
- 图中不存在平行边
- 1 <= N <= 100
- 1 <= M <= 500
[KamaCoder] 98. 所有可达路径
自己看到题目的第一想法
无, 最近越来越不自己思考了, 有赶进度的因素.
看完代码随想录之后的想法
递归遍历当前节点所有可达的节点, 直到抵达终点, 或者走到无法继续往前走的节点位置. dfs 表示深度搜索, bfs 表示广度搜索.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
// 邻接表 dfs
public class Main {
private static final List<List<Integer>> result = new ArrayList<>();
private static List<Integer> path = new ArrayList<>();
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Map<Integer, Set<Integer>> nodes = new HashMap<>();
int nodeCount = 0;
int sideCount = 0;
while (scanner.hasNext()) {
nodeCount = scanner.nextInt();
sideCount = scanner.nextInt();
for (int i = 0; i < sideCount; i++) {
int node = scanner.nextInt();
Set<Integer> toNodes = nodes.get(node);
if (toNodes == null) {
toNodes = new HashSet<Integer>();
nodes.put(node, toNodes);
}
toNodes.add(scanner.nextInt());
}
}
path.add(1);
dfs(nodes, 1, nodeCount);
// path.remove(path.size() - 1);
if (result.size() == 0) {
System.out.println("-1");
return;
}
for (int i = 0; i < result.size(); i++) {
path = result.get(i);
for (int j = 0; j < path.size() - 1; j++) {
System.out.print(path.get(j) + " ");
}
System.out.println(path.get(path.size() - 1));
}
}
private static void dfs(Map<Integer, Set<Integer>> nodes, int from, int destination) {
if (from == destination) {
result.add(new ArrayList<>(path));
return;
}
Set<Integer> toNodes = nodes.get(from);
if (toNodes == null) {
return;
}
for (Integer toNode : toNodes) {
path.add(toNode);
dfs(nodes, toNode, destination);
path.remove(path.size() - 1);
}
}
}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
// 邻接矩阵 dfs
public class Main {
private static final List<List<Integer>> result = new ArrayList<>();
private static List<Integer> path = new ArrayList<>();
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[][] nodes = null;
int nodeCount = 0;
int sideCount = 0;
while (scanner.hasNext()) {
nodeCount = scanner.nextInt();
sideCount = scanner.nextInt();
nodes = new int[nodeCount + 1][nodeCount + 1];
for (int i = 0; i < sideCount; i++) {
nodes[scanner.nextInt()][scanner.nextInt()] = 1;
}
}
path.add(1);
dfs(nodes, 1, nodeCount);
// path.remove(path.size() - 1);
if (result.size() == 0) {
System.out.println("-1");
return;
}
for (int i = 0; i < result.size(); i++) {
path = result.get(i);
for (int j = 0; j < path.size() - 1; j++) {
System.out.print(path.get(j) + " ");
}
System.out.println(path.get(path.size() - 1));
}
}
private static void dfs(int[][] nodes, int from, int destination) {
if (from == destination) {
result.add(new ArrayList<>(path));
return;
}
for (int i = 1; i < nodes[from].length; i++) {
if (nodes[from][i] != 1) {
continue;
}
path.add(i);
dfs(nodes, i, destination);
path.remove(path.size() - 1);
}
}
}
自己实现过程中遇到哪些困难
搜索路径可以用广度优先搜索吗?
题目描述
给定一个由 1(陆地)和 0(水)组成的矩阵,你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。你可以假设矩阵外均被水包围。
输入描述
第一行包含两个整数 N, M,表示矩阵的行数和列数。
后续 N 行,每行包含 M 个数字,数字为 1 或者 0。
输出描述
输出一个整数,表示岛屿的数量。如果不存在岛屿,则输出 0。
输入示例
4 5 1 1 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 1 1
输出示例
3
根据测试案例中所展示,岛屿数量共有 3 个,所以输出 3。
数据范围:
1 <= N, M <= 50
[LeetCode] 99. 岛屿数量 深搜版
自己看到题目的第一想法
这个基础题我会~
看完代码随想录之后的想法
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
// 邻接矩阵 dfs
public class Main {
private static int[][] dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
private static boolean[][] visited;
private static int result = 0;
private static int rowCount = 0;
private static int columnCount = 0;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[][] nodes = null;
int result = 0;
while (scanner.hasNext()) {
rowCount = scanner.nextInt();
columnCount = scanner.nextInt();
nodes = new int[rowCount][columnCount];
visited = new boolean[rowCount][columnCount];
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < columnCount; j++) {
nodes[i][j] = scanner.nextInt();
}
}
}
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < columnCount; j++) {
if (visited[i][j] || nodes[i][j] != 1) {
continue;
}
result++;
dfs(nodes, visited, i, j);
}
}
System.out.print(result);
}
private static void dfs(int[][] nodes, boolean[][] visited, int x, int y) {
visited[x][y] = true;
int newX;
int newY;
for (int i = 0; i < dir.length; i++) {
newX = x + dir[i][0];
newY = y + dir[i][1];
if (newX < 0 || newX >= nodes.length || newY < 0 || newY >= nodes[newX].length) {
// 超出范围
continue;
}
if (visited[newX][newY] || nodes[newX][newY] != 1) {
// 标记过了, 或者非陆地, 不处理
continue;
}
dfs(nodes, visited, newX, newY);
}
}
}
自己实现过程中遇到哪些困难
无.
[LeetCode] 99. 岛屿数量 广搜版
自己看到题目的第一想法
这题我会~
看完代码随想录之后的想法
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class Main {
private static int[][] dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
private static boolean[][] visited;
private static int result = 0;
private static int rowCount = 0;
private static int columnCount = 0;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[][] nodes = null;
boolean[][] visited = null;
int result = 0;
while (scanner.hasNext()) {
rowCount = scanner.nextInt();
columnCount = scanner.nextInt();
nodes = new int[rowCount][columnCount];
visited = new boolean[rowCount][columnCount];
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < columnCount; j++) {
nodes[i][j] = scanner.nextInt();
}
}
}
Deque<int[]> toNodes = new LinkedList<>();
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < columnCount; j++) {
if (visited[i][j] || nodes[i][j] != 1) {
continue;
}
result++;
toNodes.addLast(new int[]{i, j});
visited[i][j] = true;
bfs(nodes, visited, toNodes);
}
}
System.out.print(result);
}
private static void bfs(int[][] nodes, boolean[][] visited, Deque<int[]> toNodes) {
while (!toNodes.isEmpty()) {
int[] node = toNodes.pop();
int x = node[0];
int y = node[1];
int newX;
int newY;
for (int i = 0; i < dir.length; i++) {
newX = x + dir[i][0];
newY = y + dir[i][1];
if (newX < 0 || newX >= nodes.length || newY < 0 || newY >= nodes[newX].length) {
// 超出范围
continue;
}
if (visited[newX][newY] || nodes[newX][newY] != 1) {
// 标记过了, 或者非陆地, 不处理
continue;
}
toNodes.addLast(new int[]{newX, newY});
visited[newX][newY] = true;
}
}
}
}
自己实现过程中遇到哪些困难
无.