亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

LeetCode 841:鑰匙和房間 Keys and Rooms

標簽:
Java Python 算法

题目:

​ 有 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)#进入递归函数
點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
算法工程師
手記
粉絲
17
獲贊與收藏
44

關注作者,訂閱最新文章

閱讀免費教程

  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消