代码随想录——钥匙和房间(图论)

news2024/9/17 8:41:17

题目

有 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 号房间

思路

DFS和BFS的区别

DFS(深度优先搜索): dfs是朝一个方向去搜,不到黄河不回头,直到遇到绝境了,搜不下去了,再换方向(换方向的过程就是回溯的过程)

BFS(广度优先搜索):bfs是先把本节点所连接的所有节点遍历一遍,走到下一个节点的时候,再把连接节点的所有节点遍历一遍,搜索方向更像是发散,四面八方的搜索过程。

总结:

  • 广搜(bfs)是一圈一圈的搜索过程,广搜队列
  • 深搜(dfs)是一条路跑到黑然后再回溯,深度递归

DFS实现代码:

因为dfs朝着一个方向搜索,并且需要回溯,所以使用递归来实现最方便的

一般情况,深搜需要二维数组数组结构保存所有路径(结果集),需要一维数组保存单一路径(单条结果

dfs代码框架和回溯代码框架几乎差不多,如下:

void dfs(参数){
	if(终止条件){
		存放结果;
		return;
	}
	
	for(选择:本节点所连接的其他节点){
		处理节点;
		dfs(图,选择的节点);//递归
		(回溯,撤销处理结果);//根据题意,是否需要还原节点,即回溯
	}
}

BFS实现代码:

广搜适合解决两个点之间的最短路径问题

因为广搜是从起点出发,以起始点为中心一圈一圈进行搜索,一旦遇到终点,记录之前走过的节点就是一条最短路(正是因为BFS一圈一圈的遍历方式,所以一旦遇到终止点,那么一定是一条最短路径),即只要BFS搜到终点一定是一条最短路径

当然,也有一些问题是广搜和深搜都可以解决的,例如岛屿问题,这类问题的特征就是不涉及具体的遍历方式,只要能把相邻且相同属性的节点标记上就行。

注意:BFS实现的容器并非只能用队列实现,bfs只是仅仅需要一个容器,能保存要遍历过的元素就可以,用队列,还是用栈,甚至用数组,都是可以的。

  • 用队列的话,就是保证每一圈都是一个方向去转,例如统一顺时针或者逆时针;因为队列是先进先出,加入元素和弹出元素的顺序是没有改变的。
  • 用栈的话,可能就是第一圈顺时针遍历,第二圈逆时针遍历,第三圈又顺时针遍历;因为栈是先进后出,加入元素和弹出元素的顺序改变了。但是广搜不需要注意转圈搜索的顺序吗

所以用队列,还是用栈都是可以的,只是大家都习惯用队列(FIFO先进先出)了,只不过要清楚,BFS并不是非要用队列,用栈也可以

bfs代码框架:

void bfs(){
	初始化队列Q;
	Q = {起始节点s};
	标记s已访问;
	while(que非空){Q队首元素u;
		u出队;
		if(u == 目标状态){
			...
		}
		所有与u相邻且未被访问的点进入队列;
		标记u为已访问;
	}
}

最后回到本题,本题给出的其实是一个有向图,对于题中的示例[[1],[2],[3],[]] [[1,3],[3,0,1],[2],[0]],画成对应的图为:

在这里插入图片描述
在这里插入图片描述

当 x 号房间中有 y 号房间的钥匙时,就可以从 x 号房间去往 y 号房间。如果将这 n 个房间看成有向图中的 n 个节点,那么上述关系就可以看作是图中的 x 号点到 y号点的一条有向边。这样一来,问题就变成了给定一张有向图,询问从 0 号节点出发是否能够到达所有的节点

所以本题是一个有向图搜索全路径的问题, 只能用深搜(DFS)或者广搜(BFS)来搜。

方法一:DFS

使用深度优先搜索的方式遍历整张图,统计可以到达的节点个数,并利用数组 vis 标记当前节点是否访问过,以防止重复访问

java代码如下:

class Solution {
	//一定要定义成全局变量,否则只能一个函数调用
	int num;//记录能够到达的房间数
	boolean[] vis;//判断是否去过该房间
	
	public boolean canVisitAllRooms(List<List<Integer>> rooms){
		int n = rooms.size();
		num = 0;
		vis = new boolean[n];
		dfs(rooms,0);
		return n == num;
	}
	
	public void dfs(List<List<Integer>> rooms, int x){
		vis[x] = true;
		num++;
		for(int u : rooms.get(x)){//这里get(x)取出的是一个列表,表示的是当前房间的钥匙,即可以去往哪些房间
			if(!vis[u]){//如果u未被访问过,即没去过这个房间
				dfs(rooms,u);
			}
		}
	}
}

方法二:BFS

使用广度优先搜索的方式遍历整张图,统计可以到达的节点个数,并利用数组 vis 标记当前节点是否访问过,以防止重复访问

class Solution {
	public boolean canVisitAllRooms(List<List<Integer>> rooms){
		int n = rooms.size();
		int num = 0;//记录可以到达的节点个数
		boolean[] vis = new boolean[n];
		Queue<Integer> que = new LinkedList<Integer>();
		que.offer(0);
		vis[0] = true;
		while(!que.isEmpty()){
			int x = que.poll();
			num++;
			for(int u : rooms.get(x)){//这里get(x)取出的是一个列表,表示的是当前房间的钥匙,即可以去往哪些房间
				if(!vis[u]){//如果u未被访问过,即没去过这个房间
					que.offer(u);
					vis[u] = true;
				}
			}
		}
		return num == n;
	}
}
  • 时间复杂度:O(n+m),其中 n 是房间的数量,m 是所有房间中的钥匙数量的总数
  • 空间复杂度:O(n),其中 n 是房间的数量,主要为队列的开销

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/13595.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

tft lcd spi 驱动

tft lcd spi 驱动参考驱动uc1701SPI设备树配置背光控制IO设备树配置SPI控制引脚配置参考驱动uc1701 linux-4.1.15-imx6ul/drivers/staging/fbtftSPI设备树配置 根据原理图修改对应引脚 linux-3.10/arch/arm/boot/dts/sun8iw11p1-pinctrl.dtsi 蔽掉引脚冲突功能 linux-3.10/ar…

如何注册公司网站?【注册公司网站】

公司网站是很多公司的必备品&#xff0c;哪怕公司并不依赖线上业务&#xff0c;也会有自己的公司网站。随着互联网的发展成熟&#xff0c;其实现在注册公司网站基本上都是比较简单的&#xff0c;那么如何注册公司网站呢&#xff1f;下面给大家说一说。 一、注册公司网站前准备…

英伟达发布526.98 WHQL 显卡驱动,支持RTX 4080,三款即将上线游戏

11月16日&#xff0c;英伟达发布了526.98 WHQL 新驱动&#xff0c;支持最新发布的RTX 4080显卡。 新驱动为《蜘蛛侠:迈尔斯莫拉莱斯》、《战锤40k:暗潮》和《魔兽世界&#xff1a;巨龙时代》提供支持。此外&#xff0c;还支持《怪物猎人崛起》的DLAA更新和WRC世代-国际汽联WRC…

【FFmpeg】ffmpeg+nginx-rtmp实现视频流转发

1.应用场景 目前的摄像头厂家能提供出来的视频流格式有限&#xff0c;且chrome已经禁止了对flash的支持&#xff0c;导致像硬盘录像机这种只能提供rtsp格式流地址的摄像头无法接入Web应用&#xff0c;所以不得不对视频的流地址进行分发&#xff0c;通过代码对流地址中的数据进…

数仓开发之DWD层(三)

&#xff08;附&#xff1a;由于篇幅原因&#xff0c;这里就不在展示代码了&#xff0c;直接告诉大家思路&#xff09; 目录 五&#xff1a;交易域订单预处理表 5.1 主要任务 5.2 思路分析 5.3 图解 六&#xff1a;交易域下单事务事实表 6.1 主要任务&#xff1a; 6.2 …

泰克AFG31152函数信号发生器Tektronix AFG31152介绍

泰克AFG31152函数信号发生器Tektronix AFG31152 AFG31152 是 Tektronix 的 50 MHz 任意函数发生器。 特征&#xff1a; 的 InstaView™ 技术使工程师能够实时查看被测设备 (DUT) 的实际波形&#xff0c;而无需示波器和探头&#xff0c;从而消除了由阻抗不匹配引起的不确定性…

linux C.UTF-8和en-US.UTF-8语言环境有什么区别?(中文乱码问题)locale命令 centos、ubuntu修改编码集(没搞定!)

文章目录问题背景查看C.UTF-8和en-US.UTF-8语言环境差异关于locale修改编码集centos&#xff08;没验证&#xff09;ubuntu问题背景 我在ubuntu16.04虚拟机和英伟达盒子ubuntu18.04上分别部署了ngrest服务 用postman请求&#xff0c;ubuntu16.04虚拟机返回的中文是乱码&#…

软件测试职场焦虑之我对35岁危机的看法

目录 前言 如何理解35岁失业&#xff1f; 本质的原因是什么&#xff1f; 应对35岁失业的策略 总结 前言 这几年关于“35岁失业”的讨论甚嚣尘上&#xff0c;特别是进入疫情时代&#xff0c;身边也越来越多的人开始讨论这个话题。 一方面是疫情带来的巨大变革&#xff0c;…

SpringCloud——微服务介绍+系统架构

目录 1. 微服务介绍 2.系统架构演变 3. 单体应用架构 3.1优点&#xff1a; * 项目架构简单&#xff0c;小型项目的话&#xff0c; 开发成本低* 项目部署在一个节点上&#xff0c; 维护方便 3.2缺点&#xff1a; * 全部功能集成在一个工程中&#xff0c;对于大型项目来讲…

Data Catalog3.0:Modern Metadata for the Modern Data Stack

从2020年开始&#xff0c;在数据领域中&#xff0c;有一个比较流行的术语&#xff1a;The Modern Data Stack(现代数据堆栈)&#xff0c;简单理解就是汇集了处理海量数据的最佳工具集。这包括在最好的工具上建立数据基础设施&#xff0c;如用于数据仓库的Snowflake&#xff0c;…

传奇外网架设常见的问题及解决办法-传奇创建人物失败/不开门/PAK显示密码错误/脚本错误

传奇外网架设常见的问题及解决办法-传奇创建人物失败/不开门/PAK显示密码错误/脚本错误 在架设传奇的时候是否有遇到无法创建人物、pak密码错误等一系列情况呢&#xff1f;咱们都知道是架设不对的问题&#xff0c;但是具体是哪部分的问题&#xff0c;很多同学都不清楚&#xff…

JDK与cglib动态代理

JDK动态代理 接口类 public interface Subject {void doSomething(); }接口实现 public class RealSubject implements Subject {Overridepublic void doSomething() {System.out.println("RealSubject do something");} }InvocationHandler类 package daili;imp…

随笔记:计算机基础及进制计数法

随笔记&#xff1a;计算机基础及进制计数法 记录一下最近接触的基本的概念&#xff0c;便于想看的时候随时来翻看一下。 基础理论还是比较重要滴&#xff0c;基础理论还是比较重要滴&#xff0c;基础理论还是比较重要滴 现代计算机是用 0 和 1 来表示信息的&#xff0c;使用的…

6、行为型模式-责任链模式

一、责任链模式描述 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;为请求创建了一个接收者对象的链。这种模式给予请求的类型&#xff0c;对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。 在这种模式中&#xff0c;通常每个接收者…

Unity AVPro 使用

AVPro 感觉我写的没多大用处&#xff0c;后面看看文档再完善一些。目前的东西是可以满足一些简单的需求的。 说明 标题名称内容Unity版本Unity 2021 .1.18f1c1AVPro 版本AVPro Video - Ultra Edition 2.5.6IDEVS2022系统版本Win 10 1909撰写日期2022 11月15日晚 需要注意的地…

防孤岛保护装置在光伏行业的应用

安科瑞 华楠 应用场景 防孤岛原理&#xff1a;防孤岛保护装置检测到并网点有逆功率、频率突变、 等异常数据时&#xff0c;即发生孤岛现象时&#xff0c;装置可配合断路器快速切除并网点&#xff0c;使本站与电网侧快速脱离&#xff0c;保证整个电站和相关维护人员的生命安全 …

Go:Signal信号量的简介与实践(优雅的退出)

文章目录简介一、kill与kill9的区别二、实践&#xff1a;优雅的退出小结简介 go中的信号量 有些信号名对应着3个信号值&#xff0c;这是因为这些信号值与平台相关&#xff0c;SIGKILL和SIGSTOP这两个信号既不能被应用程序捕获&#xff0c;也不能被操作系统阻塞或忽略。 一、…

智慧管廊解决方案-最新全套文件

智慧管廊解决方案-最新全套文件一、建设背景二、建设意义三、建设目标四、思路架构综合管廊目前存在的痛点1、安全防范不足2、管理技术落后3、信息孤岛问题4、多头管理问题五、建设方案六、获取 - 智慧管廊全套最新解决方案合集一、建设背景 综合管廊一般是建于城市地下用于容…

NUMA架构详解

基本概念 为什么要有多处理器架构&#xff1f; 由于摩尔定律的失效&#xff0c;单个CPU内的晶体管的数量接近于饱和状态&#xff0c;因此单个CPU的性能已经接近饱和状态&#xff0c;这时&#xff0c;要想提高计算机的性能&#xff0c;就必须朝着多核架构发展。多核架构中&…

力扣(leetcode)刷题分享,简单题(第2期)

力扣第二期介绍1. 反转链表2. 移除链表元素3. 找链表的中间节点4. 寻找链表中的倒数第k个结点5. 合并两个有序链表总结第二期介绍 本期博客主要讲解的题目是有关链表的一些经典OJ题&#xff0c;有一定难度&#xff0c;希望大家耐心看完。 1. 反转链表 题目介绍&#xff1a; …