题目:

​ 有 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

​ 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.

示例 1:

输入: [[1],[2],[3],[]]
输出: true
解释:
我们从 0 号房间开始,拿到钥匙 1。
之后我们去 1 号房间,拿到钥匙 2。
然后我们去 2 号房间,拿到钥匙 3。
最后我们去了 3 号房间。
由于我们能够进入每个房间,我们返回 true。

示例 2:

输入:[[1,3],[3,0,1],[2],[0]]
输出:false
解释:我们不能进入 2 号房间。

提示:

  1. 1 <= rooms.length <= 1000
  2. 0 <= rooms[i].length <= 1000
  3. 所有房间中的钥匙数量总计不超过 3000

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号房间开始递归遍历就可以了。唯一需要注意的是如何判断房间是否访问过。可以用set哈希表把已访问过的房间号记录下来,最后如果哈希表长度和rooms长度相等,那么就意味着所有房间均可到达。

代码:

Set集合(Java):

class Solution {
Set<Integer> set = new LinkedHashSet<>(); public boolean canVisitAllRooms(List<List<Integer>> rooms) {
helper(rooms, 0);
return set.size() == rooms.size();//长度相等则可以到达所有房间
} private void helper(List<List<Integer>> rooms, int index) {
if (set.contains(index)) return;
set.add(index);//已访问房间号加入哈希表
for (Integer i : rooms.get(index)) {//遍历房间的每一个钥匙
helper(rooms, i);//进入递归
}
}
}

​ 可以看到用哈希表解题方法在递归期间会多出许多set函数的调用,如 set.add() 、set.contains(),相对很多这道题解题时间,这个开销是很大。对这道题而言,是完全可以用数组避免的。

Java:

class Solution {

    public boolean canVisitAllRooms(List<List<Integer>> rooms) {
int len = rooms.size();
int[] visited = new int[len];//初始化等长数组,数组每个值默认为0
helper(rooms, 0, visited);
for (int i : visited)
if (i == 0) return false;//数组中依然有0,则证明有房间未访问到
return true;
} private void helper(List<List<Integer>> rooms, int index, int[] visited) {
if (visited[index] == 1) return;//如果该房间已访问过,直接返回
visited[index] = 1;//在访问过的房间,改为1来标记
for (Integer i : rooms.get(index)) {//遍历
helper(rooms, i, visited);
}
}
}

Python:

class Solution:
def canVisitAllRooms(self, rooms: List[List[int]]) -> bool:
size=len(rooms)
self.visited = [False]*size # 初始化等长数组,默认为False,所有房间均未访问
self.helper(rooms, 0)
return all(self.visited) def helper(self, rooms: List[List[int]], index: int) -> None:
if self.visited[index]:#如果为True,该房间已访问过,直接返回
return
self.visited[index] = True #在访问的房间标记为True
for i in rooms[index]:#遍历钥匙
self.helper(rooms, i)#进入递归函数

欢迎关注微.信公.众号:爱写Bug

最新文章

  1. js判断窗体或容器滚动条到底部
  2. 工作任务:模拟淘宝登录和购物车功能:使用cookie记录登录名,下次登录时能够记得上次的登录名,使用cookie模拟购物车功能,使用session记住登录信息并验证是否登录,防止利用url打开网站,并实现退出登录功能
  3. javaBean Request生命周期
  4. Android(Xamarin)之旅(四)
  5. 【Spark】jupyter notebook
  6. java多线程系列1--线程实现与调度
  7. [转载]ExtJs4 笔记(5) Ext.Button 按钮
  8. ASP.NET项目中引用全局dll
  9. OpenCASCADE 基础
  10. HDU3988-Harry Potter and the Hide Story(数论-质因数分解)
  11. 三种字符编码:ASCII、Unicode和UTF-8
  12. win7安装ruby on rails开发环境
  13. phpmailer 的使用
  14. python列表很聪明,支持负数索引
  15. Java GC2
  16. [转]NodeBB 环境搭建
  17. c++中的前置声明
  18. B轮公司技术问题列表
  19. winform 程序调用及参数调用
  20. TFS Negotiate方式登录的IIS配置

热门文章

  1. oracle学习笔记(十七) PL/SQL高级应用
  2. 在.net 程序中使用Mustache模板字符串
  3. Python3---爬虫---抓取百度贴吧
  4. Java生鲜电商平台-App系统架构开发与设计
  5. 缓存cache(擦车)
  6. RPM包安装——手动安装
  7. 【微信小程序】template模板使用详解
  8. MySQL中日期和时间类型
  9. SparkStreaming wordCountDemo基础案例
  10. React教程:4 个 useState Hook 示例