LeetCode 841:钥匙和房间 Keys and Rooms

题目:

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

原文地址:https://www.cnblogs.com/zhangzhe532/p/11564522.html

时间: 2024-08-28 10:38:02

LeetCode 841:钥匙和房间 Keys and Rooms的相关文章

Leetcode-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 号房间外的其余所有房间都被锁住. 你可以自由地在房间之间来回走动. 如果能进入每个

841. Keys and Rooms —— weekly contest 86

题目链接:https://leetcode.com/problems/keys-and-rooms/description/ 简单DFS time:9ms 1 class Solution { 2 public: 3 void DFS(int root,vector<int>& visited,vector<vector<int>>& rooms){ 4 visited[root] = 1; 5 for(auto x : rooms[root]){ 6

leetcode841 Keys and Rooms

1 """ 2 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. 3 Formally, each room i has a list of keys rooms[i], and each key rooms[i][j]

Leetcode Weekly Contest 86

Weekly Contest 86 A:840. 矩阵中的幻方 3 x 3 的幻方是一个填充有从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等. 给定一个由整数组成的 N × N 矩阵,其中有多少个 3 × 3 的 "幻方" 子矩阵?(每个子矩阵都是连续的). 直接模拟即可,本来是签到题,由于粗心,浪费了时间. 1 class Solution { 2 public: 3 int numMagicSquaresInside(vector&l

leet

# 题名1 两数之和    2 两数相加    3 无重复字符的最长子串    4 寻找两个有序数组的中位数    5 最长回文子串    6 Z 字形变换    7 整数反转    8 字符串转换整数 (atoi)    9 回文数    10 正则表达式匹配    11 盛最多水的容器    12 整数转罗马数字    13 罗马数字转整数    14 最长公共前缀    15 三数之和    16 最接近的三数之和    17 电话号码的字母组合    18 四数之和    19 删除链表

【LeetCode】深搜DFS(共85题)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica } [98]Validate Binary Search Tree [99]Recover Binary Search Tree [100]Same Tree [101]Symmetric Tree [104]Maximum Depth of Binary Tree [105]Construct Binary Tree from Preorder and Inorder

新概念英语第三册51-60课(转)

Lesson 51  Predicting the future 预测未来 1.预测世界的未来Predicting the future是众所周知的困难.is notoriously difficult. 众所周知预测未来很困难.Predicting the future is notoriously difficult. 众所周知预测未来很困难. 2.谁过去能够曾经想象过, Who could have imagined, 在20世纪70年代中叶,in the mid 1970s, 例如,fo

越狱Season 1-Episode 11: And Then There Were 7-M

Season 1, Episode 11: And Then There Were 7-M -Michael: That one 那个 -businessman: Nice choice choice: 选择 眼光不错 -Michael: Thanks. 谢谢 -businessman: Platinum platinum: 白金 白金 Brushed. brushed: 拉过绒的 拉丝的 -Michael: Six point two five point: 点 6.25克? -busines

《基于Node.js实现简易聊天室系列之详细设计》

一个完整的项目基本分为三个部分:前端.后台和数据库.依照软件工程的理论知识,应该依次按照以下几个步骤:需求分析.概要设计.详细设计.编码.测试等.由于缺乏相关知识的储备,导致这个Demo系列的文章层次不是很清楚,索性这一章将所有的过程(前后端以及数据库)做一个介绍,下一章写完总结就OK了吧. (1)前端部分 涉及到的技术:html.css.bootstrap.jquery.jquery UI 登录/注册界面使用的是bootstrap响应式布局,即支持不同尺寸的客户端,以此提高用户的体验.在这之前