841. 钥匙和房间
有 N
个房间,开始时你位于 0
号房间。每个房间有不同的号码:0,1,2,...,N-1
,并且房间里可能有一些钥匙能使你进入下一个房间。
在形式上,对于每个房间 i
都有一个钥匙列表 rooms[i]
,每个钥匙 rooms[i][j]
由 [0,1,...,N-1]
中的一个整数表示,其中 N = rooms.length
。 钥匙 rooms[i][j] = v
可以打开编号为 v
的房间。
最初,除 0
号房间外的其余所有房间都被锁住。
你可以自由地在房间之间来回走动。
如果能进入每个房间返回 true
,否则返回 false
。
示例 1:
代码语言:javascript复制输入: [[1],[2],[3],[]]
输出: true
解释:
我们从 0 号房间开始,拿到钥匙 1。
之后我们去 1 号房间,拿到钥匙 2。
然后我们去 2 号房间,拿到钥匙 3。
最后我们去了 3 号房间。
由于我们能够进入每个房间,我们返回 true。
示例 2:
代码语言:javascript复制输入:[[1,3],[3,0,1],[2],[0]]
输出:false
解释:我们不能进入 2 号房间。
提示:
1 <= rooms.length <= 1000
0 <= rooms[i].length <= 1000
- 所有房间中的钥匙数量总计不超过
3000
。
解题思路
题目简直就是为BFS
而生的题目,直接套入BFS
即可。
代码语言:javascript复制解题代码(C语言)
struct Queue
{
int arr[2010];
int top;
int rear;
}queue;
bool canVisitAllRooms(int** rooms, int roomsSize, int* roomsColSize){
queue.top = -1;
queue.rear = -1;
memset(queue.arr,0,sizeof(queue.arr));
//统计已经访问过的房间数量
int visited_count = 0;
int visited_arr[roomsSize];
//未开始前标记每个房间都没有被访问
memset(visited_arr,0,sizeof(visited_arr));
//队列为空,从 0 开始入队
queue.arr[ queue.rear] = 0;
//标记入队
visited_arr[0] = 1;
visited_count ;
while(!(queue.rear - queue.top == 0))
{
//队列不为空,取出
int start_room = queue.arr[ queue.top];
if(!visited_arr[start_room])
{
visited_arr[start_room] = 1;
visited_count ;
}
int i = 0;
for(int i=0;i<roomsColSize[start_room];i )
{
if(!visited_arr[rooms[start_room][i]])
{
//放入队伍
visited_arr[rooms[start_room][i]] = 1;
visited_count ;
//部分剪枝
if(visited_count == roomsSize)
{
return true;
}
queue.arr[ queue.rear] = rooms[start_room][i];
}
}
}
if(visited_count < roomsSize) return false;
return true;
}