【问题描述】[中等]
【解答思路】
当 xx 号房间中有 yy 号房间的钥匙时,我们就可以从 xx 号房间去往 yy 号房间。如果我们将这 nn 个房间看成有向图中的 nn 个节点,那么上述关系就可以看作是图中的 xx 号点到 yy 号点的一条有向边。
这样一来,问题就变成了给定一张有向图,询问从 00 号节点出发是否能够到达所有的节点。
用visit数组或者Set记录已经访问的节点
1. DFS
使用深度优先搜索的方式遍历整张图,统计可以到达的节点个数,并利用数组 vis 标记当前节点是否访问过,以防止重复访问。
复杂度
class Solution {boolean[] vis;int num;public boolean canVisitAllRooms(List<List<Integer>> rooms) {int n = rooms.size();num = 0;vis = new boolean[n];dfs(rooms, 0);return num == n;}public void dfs(List<List<Integer>> rooms, int x) {vis[x] = true;num++;for (int it : rooms.get(x)) {if (!vis[it]) {dfs(rooms, it);}}}
}
2. BFS
用广度优先搜索的方式遍历整张图,统计可以到达的节点个数,并利用数组 vis /Set标记当前节点是否访问过,以防止重复访问。
复杂度
class Solution {public boolean canVisitAllRooms(List<List<Integer>> rooms) {int n = rooms.size(), num = 0;boolean[] vis = new boolean[n];Queue<Integer> que = new LinkedList<Integer>();vis[0] = true;que.offer(0);while (!que.isEmpty()) {int x = que.poll();num++;for (int it : rooms.get(x)) {if (!vis[it]) {vis[it] = true;que.offer(it);}}}return num == n;}
}
public boolean canVisitAllRooms(List<List<Integer>> rooms) {Stack<Integer> a = new Stack<>();HashSet<Integer> set = new HashSet<Integer>();set.add(0);a.add(0);while(!a.isEmpty()){int i =a.pop();for(int j:rooms.get(i)){if(!set.contains(j)){a.add(j);set.add(j);if (rooms.size() == set.size()) return true;}}}return (rooms.size() == set.size()) ;}
【总结】
1. DFS 递归回溯 BFS 队列
2.审题!!! 思考后再行动
转载链接:https://leetcode-cn.com/problems/keys-and-rooms/solution/yao-chi-he-fang-jian-by-leetcode-solution/