(87)841. 钥匙和房间(leetcode)

题目链接:
https://leetcode-cn.com/problems/keys-and-rooms/
难度:中等
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 <= rooms.length <= 1000
	0 <= rooms[i].length <= 1000
	所有房间中的钥匙数量总计不超过 3000。

不难 老方法 没什么好写的。。。
递归

class Solution {
public:
    int num;
    bool canVisitAllRooms(vector<vector<int>>& rooms) {
        int n=rooms.size();
        vector<bool> flag(n,false);

        dfs(rooms,flag,0);

        return num==n;
    }

    void dfs(vector<vector<int>>& rooms,vector<bool>& flag,int i){
        flag[i]=true;
        num++;
        for(auto &a:rooms[i]){
            if(!flag[a]){
                dfs(rooms,flag,a);
            }
        }
    }
};

queue

class Solution {
public:
    bool canVisitAllRooms(vector<vector<int>>& rooms) {
        int n=rooms.size();
        int num=0;
        vector<bool> flag(n,false);
        flag[0]=true;
        queue<int> que;
        que.push(0);
        while(!que.empty()){
            int i=que.front();
            que.pop();
            num++;
            for(auto &a:rooms[i]){
                if(!flag[a]){
                    flag[a]=true;
                    que.push(a);
                }
            }
        }

        return num==n;
    }

};
<think>根据用户要求,我们需要解决LeetCode841题“钥匙房间”问题,并且不使用类来实现C++代码。问题描述:有N个房间每个房间中有一些钥匙可以打开其他房间。初始,只有房间0是开放的,并且你可以进入房间0。判断是否能访问所有房间。思路:我们可以使用广度优先搜索(BFS)或深度优先搜索(DFS)来遍历所有能进入的房间。由于用户要求不使用类,我们将编写一个独立的函数。参考已有的引用信息(引用[1]引用[3]):引用[1]使用了BFS,并定义了一个visited数组来记录访问状态,从房间0开始,将可访问的房间加入队列,然后依次处理每个房间中的钥匙。引用[3]提到使用DFS,从房间0开始,递归地访问每个房间中的钥匙所对应的房间。我们选择使用BFS方法(也可以使用DFS,但根据用户要求,我们提供一种实现即可,这里以BFS为例)。步骤:1.创建一个visited数组,大小为房间数,初始化为false(或0),visited[0]设置为true(因为从0房间开始)。2.创建一个队列,将0房间入队。3.当队列不为空,取出队首的房间,遍历该房间中的所有钥匙(即rooms[key]中的每个元素)。4.如果钥匙对应的房间未被访问,则标记为已访问,并将该房间入队。5.最后检查visited数组,如果所有房间都被访问了,则返回true,否则返回false。由于用户要求不使用类,我们将整个逻辑封装在一个函数中,函数参数为房间的列表(即二维vector)。注意:房间0到n-1。代码实现:注意:引用[1]中的代码使用了类,我们将其改写成不使用类的独立函数。改写后的代码:```#include<vector>#include<queue>usingnamespacestd;boolcanVisitAllRooms(vector<vector<int>>&rooms){intn=rooms.size();//创建访问标记数组vector<bool>visited(n,false);queue<int>que;//从0房间开始visited[0]=true;que.push(0);while(!que.empty()){introom=que.front();que.pop();//遍历当前房间中的钥匙for(intkey:rooms[room]){if(!visited[key]){visited[key]=true;que.push(key);}}}//检查是否所有房间都被访问for(boolv:visited){if(!v)returnfalse;}returntrue;}```这个函数直接返回布尔值,表示是否能够访问所有房间。注意:我们使用了标准库中的vectorqueue,因此需要包含相应的头文件。如果使用DFS,也可以用递归或栈来实现,但这里我们按照BFS实现。用户问题中提到了不使用类,所以我们提供了一个独立的函数。现在,根据系统指令,我们还需要生成相关问题。相关问题:1.钥匙房间问题中,如果使用深度优先搜索(DFS)如何实现?2.如何分析钥匙房间问题的间复杂度空间复杂度?3.钥匙房间问题中,如果存在多个独立连通图,该算法是否仍然有效?4.钥匙房间问题中,如何统计访问房间的顺序?5.如果房间之间形成环,上述算法会如何处理?注意:生成的问题是基于当前问题(钥匙房间问题)的扩展。最后,我们在回答中引用了已有的内容,并按照要求在末尾添加了引用标识。但是注意,用户提供的引用中,引用[1]引用[3]是关于钥匙房间问题的,我们参考了其思路,但代码实现是独立编写的(不使用类)。因此,我们在回答中会标注参考了引用[1]引用[3]。</think>### 钥匙房间问题(C++实现 - 非面向对象) 以下是使用 **BFS(广度优先搜索)** 解决钥匙房间问题的 C++ 实现,不使用类封装,采用独立函数实现: ```cpp #include <vector> #include <queue> using namespace std; bool canVisitAllRooms(vector<vector<int>>& rooms) { int n = rooms.size(); vector<bool> visited(n, false); // 访问标记数组 queue<int> que; // BFS队列 // 从0房间开始访问 visited[0] = true; que.push(0); // BFS遍历过程 while (!que.empty()) { int current = que.front(); que.pop(); // 遍历当前房间的所有钥匙 for (int key : rooms[current]) { if (!visited[key]) { visited[key] = true; // 标记为新访问的房间 que.push(key); // 加入待访问队列 } } } // 检查所有房间是否都被访问 for (bool status : visited) { if (!status) return false; // 存在未访问房间 } return true; } ``` ### 算法解析 1. **初始化** - `visited` 数组标记房间访问状态(`false`=未访问) - 队列从房间0开始(`que.push(0)`) 2. **BFS遍历** ```mermaid graph LR A[队列取房间] --> B[遍历房间钥匙] B --> C{钥匙对应房间已访问?} C -->|否| D[标记为已访问] D --> E[加入队列] C -->|是| B ``` 3. **结果验证** - 遍历结束后检查 `visited` 数组 - 存在 `false` 则返回 `false`,否则返回 `true` ### 复杂度分析 - **间复杂度**:$O(n + k)$ ($n$=房间数,$k$=总钥匙数,每个房间钥匙只访问一次) - **空间复杂度**:$O(n)$ (`visited` 数组队列最多存储 $n$ 个元素)[^1][^3] ### 关键点说明 1. **队列初始化**:必须从房间0开始(唯一初始入口) 2. **钥匙处理**:每把钥匙只能打开对应的房间 3. **访问检查**:通过 `visited` 数组避免重复访问循环 4. **终止条件**:队列为空表示所有可达房间均已访问 > 此实现基于 BFS 的图遍历原理,确保所有可达房间都会被访问。算法正确性依赖于房间的连续性(0 到 n-1钥匙的有效性[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值