【LeetCode】841. 钥匙和房间
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],[2],[3],[]]
输出: true
解释:
我们从 0 号房间开始,拿到钥匙 1。
之后我们去 1 号房间,拿到钥匙 2。
然后我们去 2 号房间,拿到钥匙 3。
最后我们去了 3 号房间。
由于我们能够进入每个房间,我们返回 true。
输入:[[1,3],[3,0,1],[2],[0]]
输出:false
解释:我们不能进入 2 号房间。
解法一:深度优先(DFS)
当 x 号房间中有 y 号房间的钥匙时,我们就可以从 x 号房间去往 y 号房间。如果我们将这 n 个房间看成有向图中的 n 个节点,那么上述关系就可以看作是图中的 x 号点到 y 号点的一条有向边。
这样一来,问题就变成了给定一张有向图,询问从 0 号节点出发是否能够到达所有的节点。
深度优先的意思就是先进入第一个房,然后拿出第一把钥匙,去开下一个房,然后再拿到这个房的第一个钥匙,再去开下一个,直到没钥匙了,退回上一个房,重复以往。这是一个递归的过程,和二叉树的遍历一样。
可以用一个数组来记录到达过哪个房间,防止重复计算。
函数功能:遍历房间
1.终止条件:把第0个房间的钥匙拿完;
2.该做什么:每个房间应该做什么呢,判断数组标志那个房间去过没有,去过了就跳过,没去过就进去,并把标志位置为true。计数器加1.最后看是否等于房间个数。
class Solution {
boolean[] vis;
int num = 0;
public boolean canVisitAllRooms(List<List<Integer>> rooms) {
int n = rooms.size();
vis = new boolean[n]; //设置第n个房间是否打开过的标志位;
canVisitAllRooms(rooms, 0);
return num == n; //查看是否遍历完;
}
private void canVisitAllRooms(List<List<Integer>> rooms, int roomnum){
vis[roomnum] = true;
num++;
for(int i : rooms.get(roomnum)){
if(!vis[i]){ //没有访问过就进去;
canVisitAllRooms(rooms, i);
}
}
}
}
解法二:广度优先(BFS)
广度优先的意思就是我们不拿到一个钥匙走到头了,我们一个房间一个房间的进,拿到第一个房间的钥匙,把第一个房间里的钥匙对应的门都打开,然后再去第二个房间。这样一个一个的进。
class Solution {
public boolean canVisitAllRooms(List<List<Integer>> rooms) {
int n = rooms.size();
boolean[] vis = new boolean[n]; //标志位就是防止被重复遍历;
int num = 0;
Queue<Integer> queue = new LinkedList<>();
vis[0] = true; //设置0号访问过,为了防止节点多次入队,需要在入队前将其设置为已访问;
queue.add(0); //0号房间入队;
while(!queue.isEmpty()){
int x = queue.poll();
num++;
for(int i : rooms.get(x)){
if(!vis[i]){ //没有被访问过;
vis[i] = true;
queue.add(i); //保证入队的都是没有被遍历过的;
}
}
}
return n == num;
}
}
体会
- 1.只要是广度优先的,肯定要用队列,天然是在一起的。 一边弹出,一边遍历,弹出一个以后,就把它的孩子或者是它的关联入队,保证把这一层,或这个节点的都弹出了,接着继续弹下一层或者下一个节点的。
- 2.树的BFS:先把root节点入队,然后再一层一层的遍历。
图的BFS也是一样的,与树的BFS的区别是:- 1.树只有一个root,而图可以有多个源点,所有首先需要将多个源点入队。
- 2.树是有向的因此不需要标志是否访问过,而对于无向图而言,必须得标志是否访问过!并且为了防止某个节点多次入队,需要在入队前将其设置为已访问!
- 3.树用DFS比较多,图用BFS比较多;
【LeetCode】841. 钥匙和房间的更多相关文章
- Leetcode-841. 钥匙和房间
题目 有 N 个房间,开始时你位于 0 号房间.每个房间有不同的号码:0,1,2,...,N-1,并且房间里可能有一些钥匙能使你进入下一个房间. 在形式上,对于每个房间 i 都有一个钥匙列表 room ...
- LeetCode 841:钥匙和房间 Keys and Rooms
题目: 有 N 个房间,开始时你位于 0 号房间.每个房间有不同的号码:0,1,2,...,N-1,并且房间里可能有一些钥匙能使你进入下一个房间. 在形式上,对于每个房间 i 都有一个钥匙列表 ...
- [LeetCode] 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 ...
- [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 ...
- LeetCode841 钥匙和房间
有 N 个房间,开始时你位于 0 号房间.每个房间有不同的号码:0,1,2,...,N-1,并且房间里可能有一些钥匙能使你进入下一个房间. 在形式上,对于每个房间 i 都有一个钥匙列表 rooms[i ...
- [LeetCode] Exam Room 考试房间
In an exam room, there are N seats in a single row, numbered 0, 1, 2, ..., N-1. When a student enter ...
- LeetCode 841. Keys and Rooms
原题链接在这里:https://leetcode.com/problems/keys-and-rooms/ 题目: There are N rooms and you start in room 0. ...
- Swift LeetCode 目录 | Catalog
请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift 说明:题目中含有$符号则为付费题目. 如 ...
- Leetcode Weekly Contest 86
Weekly Contest 86 A:840. 矩阵中的幻方 3 x 3 的幻方是一个填充有从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等. 给定一个 ...
随机推荐
- C++中封装和继承的访问权限
众所周知,C++面向对象的三大特性为:封装,继承和多态.下面我们就先对封装做一些简单的了解.封装是通过C++中的类来完成的,类是一种将抽象转换为用户定义类型的工具.类的定义如下: class circ ...
- 玩转STM32MP157- 使用 u8g2 驱动 OLED 12864(SSD1306)
环境 硬件环境:STM32MP157C-DK2 软件: MPU上使用ST官方提供的STM32MP15x OpenSTLinux Starter Package 编译系统:Ubuntu 1604 64b ...
- 并发王者课-铂金6:青出于蓝-Condition如何把等待与通知玩出新花样
欢迎来到<[并发王者课](https://juejin.cn/post/6967277362455150628)>,本文是该系列文章中的**第19篇**. 在上一篇文章中,我们介绍了阻塞队 ...
- Linux 中的 AutoHotKey 键映射替代方案
1. Windows 之 AutoHotKey 初次了解AutoHotKey,是在Win 下最爱效率神器:AutoHotKey | 晚晴幽草轩这篇博客中,博主有对AutoHotKey作详细介绍,这里不 ...
- 【原创】SystemVerilog中的多态和虚方法
封装可以隐藏实现细节,使代码模块化,继承可以扩展已经存在的代码模块,目的都是为了代码重用.多态是为了实现接口的重用.在SystemVerilog中,子类和父类之间多个子程序使用同一个名字的现象称为Sy ...
- mysql字符集utf8和utf8mb4区别
1.起因 公司游戏项目上线第一天,出现单个区服异常宕机的问题,根据日志排查下来,连接数据的时候报错,后面排查是因为有玩家插入Emoji 等表情导致无法存储如数据库,数据库字符集编码为utf8,后续改成 ...
- 3.QT屏幕分辨率适配
需求:qt的窗口.组件.字体需要适配屏幕分辨率. 思路:qt是根据显示器的物理长度或者宽度于分辨率的关系来计算dpi 实现: #if(QT_VERSION >= QT_VERSION_CHECK ...
- SpringBoot Validation参数校验 详解自定义注解规则和分组校验
前言 Hibernate Validator 是 Bean Validation 的参考实现 .Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的 ...
- PS 快速抠图
1.选择矩形选框工具-->选择图中要抠掉的地方-->右键填充-->确定
- uniapp 微信小程序扫码处理
1.view 代码 <view class="v-main-scan"> <uni-icons @click="scanCode" clas ...