编程语言
首页 > 编程语言> > [算法题解详细]DFS解力扣841钥匙和房间

[算法题解详细]DFS解力扣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

输入: [[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。

思路

这一题看起来文字很多,但其实不是特别难,这题的核心就在于

从0号房间出发,遍历0号房间的钥匙列表,然后用相应的钥匙去开相应的房间,然后再遍历开的相应房间的钥匙列表,再去开门

核心就在于进房间,拿钥匙,再进房间,再拿钥匙,这里有人可能就会有疑问了,那代码什么时候终止呢?

问的好,我们只需要定义一个大小为N的数组用来表示,每间房间的访问情况,如果已经访问过则为1,没有访问过则为初始值0,这样我们从0号房间出发,一直到最后再没有新的房间能打开结束

废话少说,下面进入代码

代码

首先在主函数中我们做的就是获取房间数量然后初始化记录数组,用于记录房间的访问情况,初始时初始化为0

然后进入dfs函数,传入0作为第一次访问的房间号

class Solution {
public:
    bool canVisitAllRooms(vector<vector<int>>& rooms) {
        int m = rooms.size();
        vector<int> record(m , 0);
        dfs(rooms, 0, record);
    }
};

然后进入dfs函数中,首先我们把当前访问的房间的记录数组的值改为1,表示已经访问过

 void dfs(vector<vector<int>>& array, int u, vector<int>& record, int n) {
        record[u] = 1;
}

然后我们遍历这个房间的钥匙列表,依靠每一个钥匙去访问相应的房间,这里要注意一个细节

因为钥匙是可以重复的,比如0号房间里可能有1号房间的钥匙,2号房间里也可能有1号房间的钥匙,所以这里要做一个剪枝,如果钥匙对应的房间已经访问过了,那么就跳过这把钥匙,避免重复计算

然后要注意dfs函数u这个参数表示的是钥匙对应的相应房间号,所以我们要把钥匙值传入

 void dfs(vector<vector<int>>& array, int u, vector<int>& record, int n) {
        record[u] = 1;
        for(auto number : array[u]) {
            if(!record[number]){
                dfs(array, number, record, n);
            }
        }
}

dfs函数结束后我们遍历一遍记录数组,如果还有值为0就代表还有房间没进入,则直接返回false,循环外直接返回true

最后是完整代码:

class Solution {
public:
    void dfs(vector<vector<int>>& array, int u, vector<int>& record, int n) {
        record[u] = 1;
        for(auto number : array[u]) {
            if(!record[number]){
                dfs(array, number, record, n);
            }
        }
    }
    bool canVisitAllRooms(vector<vector<int>>& rooms) {
        int m = rooms.size();
        vector<int> record(m , 0);
        dfs(rooms, 0, record, m);
        for(int i = 0; i < m; i++) {
            if(!record[i]) {
                return false;
            }
        }
        return true;
    }
};

标签:841,题解,房间,DFS,record,vector,钥匙,dfs,rooms
来源: https://blog.csdn.net/m0_61607810/article/details/121318675