• LeetCode 841. 钥匙和房间 | Python


    841. 钥匙和房间


    题目来源:力扣(LeetCode)https://leetcode-cn.com/problems/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。

    示例 1:

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

    示例 2:

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

    提示:

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

    解题思路


    思路:DFS、BFS

    先看题目,题目要求从 0 号房间开始,问是否能够进入每个房间?其中,0 号房间最开始是打开的,而其他的房间则全部锁住。理论上,每个房间里面都有钥匙(但根据 提示 2 可能无)对应其他房间的钥匙(包括当前房间,如示例 2 的 1 号房间)。

    在这里,我们可以发现,这里像是一个有向图,而钥匙决定两点的有向边,从某个点开始,问是否能够到达所有的点?

    题目中给定的数组就是 邻接表,那么我们可以考虑使用深度优先搜索(DFS)、广度优先搜索(BFS)的思路,遍历搜索整个图,看是否能够搜索所有的点。这里我们用 set 来记录已访问的房间。

    具体代码实现如下。

    DFS

    class Solution:
        def canVisitAllRooms(self, rooms: List[List[int]]) -> bool:
            # 用集合存储访问房间,保证其不重复
            # 后续直接与 rooms 数量对比,得到是否访问所有房间
            visited = set()
    
            def dfs(cur_room):
                # 先添加标记已访问
                visited.add(cur_room)
                # 这里获得钥匙
                next_keys = rooms[cur_room]
                # 根据钥匙去访问其他房间,已访问的跳过
                for i in range(len(next_keys)):
                    next_room = next_keys[i]
                    if next_room not in visited:
                        dfs(next_room)
                
            
            dfs(0)
    
            return len(visited) == len(rooms)
    

    BFS

    class Solution:
        def canVisitAllRooms(self, rooms: List[List[int]]) -> bool:
            # 集合存储已访问房间,保证其不重复
            visited = set()
    
            from collections import deque
            queue = deque()
            
            # 同样从 0 号房间开始
            visited.add(0)
            queue.append(0)
            
            while queue:
                # 先获取队列中的房间号
                room_num = queue.popleft()
                # 去对应房间找钥匙
                next_keys = rooms[room_num]
    
                for i in range(len(next_keys)):
                    # 对应钥匙去对应的房间
                    next_room_num = next_keys[i]
                    # 判断是否访问,访问过则跳过
                    if next_room_num not in visited:
                        visited.add(next_room_num)
                        queue.append(next_room_num)
            
            # 对比 visited 与 rooms
            return len(visited) == len(rooms)
    

    欢迎关注


    公众号 【书所集录

  • 相关阅读:
    观察是快速成长的一个牛逼技能
    linux下使用lftp的小结(转)
    关于升级cocos2d-x网络库来支持ipv6、https,以及socket怎么支持ipv6
    cocos2dx支持arm64
    android studio 命令行编译cocos 3.15.1 安卓工程
    认识Android.mk和Application.mk
    mac os x下Android Studio3.0 配置本地 Gradle
    图片转成base64编码
    集成pbc
    6、SpringMVC:结果跳转方式 和 数据提交时的处理
  • 原文地址:https://www.cnblogs.com/yiluolion/p/13589077.html
Copyright © 2020-2023  润新知