有
n
个房间,房间按从0
到n - 1
编号。最初,除 0号房间外的其余所有房间都被锁住。你的目标是进入所有的房间。然而,你不能在没有获得钥匙的时候进入锁住的房间。
当你进入一个房间,你可能会在里面找到一套不同的钥匙,每把钥匙上都有对应的房间号,即表示钥匙可以打开的房间。你可以拿上所有钥匙去解锁其他房间。
给你一个数组rooms
其中rooms[i]
是你进入i
号房间可以获得的钥匙集合。如果能进入 所有 房间返回true
,否则返回false
。
示例 1:
输入:rooms = [[1],[2],[3],[]]
输出:true
解释:
我们从 0 号房间开始,拿到钥匙 1。
之后我们去 1 号房间,拿到钥匙 2。
然后我们去 2 号房间,拿到钥匙 3。
最后我们去了 3 号房间。
由于我们能够进入每个房间,我们返回 true。
示例 2:
输入:rooms = [[1,3],[3,0,1],[2],[0]]
输出:false
解释:我们不能进入 2 号房间
解题思路
本文采用对有向图的DFS,即:
通过深度优先的方法去遍历每一个能到达的结点,并每到达一个新房间,就num++
,最后和比较num
和房间的数量的关系,如果相等则全部访问了,如果不相等,则有的房间没有访问
class Solution {
public:
vector<int> vis;
int num;
void dfs(vector<vector<int>>& rooms, int x) {
vis[x] = true; // 标记当前房间已经被访问了
num++;
for (auto& it : rooms[x]) { // 进入该房间拿钥匙
if (!vis[it]) { // 如果发现该钥匙对应的房间没有被标记
dfs(rooms, it); // 再次调用dfs进行标记
}
}
}
bool canVisitAllRooms(vector<vector<int>>& rooms) {
int n = rooms.size(); // 获取房间数量
num = 0;
vis.resize(n);
dfs(rooms, 0); // 从0号房间开始
return num == n; // 判断
}
};