There are N rooms and you start in room 0.  Each room has a distinct number in 0, 1, 2, ..., N-1, and each room may have some keys to access the next room.

Formally, each room i has a list of keys rooms[i], and each key rooms[i][j] is an integer in [0, 1, ..., N-1] where N = rooms.length.  A key rooms[i][j] = v opens the room with number v.

Initially, all the rooms start locked (except for room 0).

You can walk back and forth between rooms freely.

Return true if and only if you can enter every room.

Example 1:

Input: [[1],[2],[3],[]]
Output: true
Explanation:
We start in room 0, and pick up key 1.
We then go to room 1, and pick up key 2.
We then go to room 2, and pick up key 3.
We then go to room 3. Since we were able to go to every room, we return true.

Example 2:

Input: [[1,3],[3,0,1],[2],[0]]
Output: false
Explanation: We can't enter the room with number 2.

Note:

  1. 1 <= rooms.length <= 1000
  2. 0 <= rooms[i].length <= 1000
  3. The number of keys in all rooms combined is at most 3000.

这道题给了我们一些房间,房间里有一些钥匙,用钥匙可以打开对应的房间,说是起始时在房间0,问最终是否可以打开所有的房间。这不由得让博主想起了惊悚片《万能钥匙》,还真是头皮发麻啊。赶紧扯回来,这是一道典型的有向图的遍历的题,邻接链表都已经建立好了,这里直接遍历就好了,这里先用 BFS 来遍历。使用一个 HashSet 来记录访问过的房间,先把0放进去,然后使用 queue 来辅助遍历,同样将0放入。之后进行典型的 BFS 遍历,取出队首的房间,然后遍历其中的所有钥匙,若该钥匙对应的房间已经遍历过了,直接跳过,否则就将钥匙加入 HashSet。此时看若 HashSet 中的钥匙数已经等于房间总数了,直接返回 true,因为这表示所有房间已经访问过了,否则就将钥匙加入队列继续遍历。最后遍历结束后,就看 HashSet 中的钥匙数是否和房间总数相等即可,参见代码如下:

解法一:

class Solution {
public:
bool canVisitAllRooms(vector<vector<int>>& rooms) {
unordered_set<int> visited{{}};
queue<int> q{{}};
while (!q.empty()) {
int t = q.front(); q.pop();
for (int key : rooms[t]) {
if (visited.count(key)) continue;
visited.insert(key);
if (visited.size() == rooms.size()) return true;
q.push(key);
}
}
return visited.size() == rooms.size();
}
};

我们也可以使用递归的解法来做,还是使用 HashSet 来记录访问过的房间,递归函数还需要传进当前的房间,还有 HashSet,首先将当前房间加入 HashSet,然后遍历此房间中的所有钥匙,如果其对应的房间没有访问过,则调用递归函数,参见代码如下:

解法二:

class Solution {
public:
bool canVisitAllRooms(vector<vector<int>>& rooms) {
unordered_set<int> visited;
helper(rooms, , visited);
return visited.size() == rooms.size();
}
void helper(vector<vector<int>>& rooms, int cur, unordered_set<int>& visited) {
visited.insert(cur);
for (int key : rooms[cur]) {
if (!visited.count(key)) helper(rooms, key, visited);
}
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/841

参考资料:

https://leetcode.com/problems/keys-and-rooms/

https://leetcode.com/problems/keys-and-rooms/discuss/133944/Java-8-lines

https://leetcode.com/problems/keys-and-rooms/discuss/133855/Straight-Forward

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Keys and Rooms 钥匙与房间的更多相关文章

  1. 【LeetCode】841. 钥匙和房间

    841. 钥匙和房间 知识点:图:递归 题目描述 有 N 个房间,开始时你位于 0 号房间.每个房间有不同的号码:0,1,2,...,N-1,并且房间里可能有一些钥匙能使你进入下一个房间. 在形式上, ...

  2. Leetcode-841. 钥匙和房间

    题目 有 N 个房间,开始时你位于 0 号房间.每个房间有不同的号码:0,1,2,...,N-1,并且房间里可能有一些钥匙能使你进入下一个房间. 在形式上,对于每个房间 i 都有一个钥匙列表 room ...

  3. [LeetCode] 253. Meeting Rooms II 会议室 II

    Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si ...

  4. LC 841. Keys and Rooms

    There are N rooms and you start in room 0.  Each room has a distinct number in 0, 1, 2, ..., N-1, an ...

  5. LeetCode 841:钥匙和房间 Keys and Rooms

    题目: ​ 有 N 个房间,开始时你位于 0 号房间.每个房间有不同的号码:0,1,2,...,N-1,并且房间里可能有一些钥匙能使你进入下一个房间. ​ 在形式上,对于每个房间 i 都有一个钥匙列表 ...

  6. [Swift]LeetCode841. 钥匙和房间 | Keys and Rooms

    There are N rooms and you start in room 0.  Each room has a distinct number in 0, 1, 2, ..., N-1, an ...

  7. 【LeetCode】841. Keys and Rooms 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS BFS 日期 题目地址:https://le ...

  8. [LeetCode] 864. Shortest Path to Get All Keys 获得所有钥匙的最短路径

    We are given a 2-dimensional grid. "." is an empty cell, "#" is a wall, "@& ...

  9. LeetCode 841. Keys and Rooms

    原题链接在这里:https://leetcode.com/problems/keys-and-rooms/ 题目: There are N rooms and you start in room 0. ...

随机推荐

  1. 使用nc传输文件和目录【转】

    方法1,传输文件演示(先启动接收命令) 使用nc传输文件还是比较方便的,因为不用scp和rsync那种输入密码的操作了 把A机器上的一个rpm文件发送到B机器上 需注意操作次序,receiver先侦听 ...

  2. session前后台交互

    下面是需求需要,不同的人群进来显示不同,但是还必须是这个走到哪都的存在,不能说点击别的页面,下面红框处的数据就没有了,必须是存在的并且登陆的类型不一样,显示的也不一样,开始的时候想到的是直接调用方法, ...

  3. JVM内存模型分析(一个程序运行的例子)

    (.class字节码)类加载到内存之后,内存模型:(ps:.class文件可以通过javap 指令反编译成一个可读文件) 1.java栈,本地方法栈,程序计数器(每个线程私有) 看如下程序: 以该程序 ...

  4. JAVA 三元运算符 求最大值

    package Code428; import java.util.Scanner; public class CodeScannerMax { public static void main(Str ...

  5. 大前端服务器渲染 发布和部署 Vue + vue(SSR)

    https://blog.csdn.net/sinat_15951543/article/details/80109521    就是到服务器dist 下面 npm run start & 然 ...

  6. Lesson 2-1 (数据结构,序列通用的操作)

    2.0 数据结构 --- 数据结构是以某种方式组合起来的数据元素集合. --- python的常见的数据结构 2.1 序列(sequence) --- 序列中的每个元素都有编号,即索引(也称为下标). ...

  7. C#获取指定的文件是否是内部特殊版本的代码

    把内容过程经常用到的内容片段珍藏起来,下面的内容内容是关于C#获取指定的文件是否是内部特殊版本的内容,希望对各朋友有所用处. using System;using System.Diagnostics ...

  8. 模块2 hashlib;configparser; logging;

    hashlib模块: hashlib模块提供了提供了常用的摘要算法,例如MD5,SHA1等. 什么是摘要算法呢?摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度固定的数据 ...

  9. 公设基础equals

    1#  覆盖equals方法的通用约定 1.自反性(reflexive) 自己跟自己的比较必须返回true 2.对称性(symmetric) x=y那么y=z 3.传递性(transitive) x= ...

  10. Jenkins编辑或替换All view

    为什么我不能编辑“All”view? 这是因为它的类型是“All”而不是“List”,并且“All”类型是不可编辑的.你只能有一个“All”类型的view. 如果你想编辑这个View,你将不得不创建一 ...