Leetcode.1559 二维网格图中探测环
题目链接
Leetcode.1559 二维网格图中探测环
rating : 1838
题目描述
给你一个二维字符网格数组 g r i d grid grid ,大小为 m x n ,你需要检查 g r i d grid grid 中是否存在 相同值 形成的环。
一个环是一条开始和结束于同一个格子的长度 大于等于 4 4 4 的路径。对于一个给定的格子,你可以移动到它上、下、左、右四个方向相邻的格子之一,可以移动的前提是这两个格子有 相同的值 。
同时,你也不能回到上一次移动时所在的格子。比方说,环 ( 1 , 1 ) − > ( 1 , 2 ) − > ( 1 , 1 ) (1, 1) -> (1, 2) -> (1, 1) (1,1)−>(1,2)−>(1,1) 是不合法的,因为从 ( 1 , 2 ) (1, 2) (1,2) 移动到 ( 1 , 1 ) (1, 1) (1,1) 回到了上一次移动时的格子。
如果 g r i d grid grid 中有相同值形成的环,请你返回 true ,否则返回 false 。
示例 1:

输入:grid = [[“a”,“a”,“a”,“a”],[“a”,“b”,“b”,“a”],[“a”,“b”,“b”,“a”],[“a”,“a”,“a”,“a”]]
输出:true
解释:如下图所示,有 2 个用不同颜色标出来的环:
示例 2:

输入:grid = [[“c”,“c”,“c”,“a”],[“c”,“d”,“c”,“c”],[“c”,“c”,“e”,“c”],[“f”,“c”,“c”,“c”]]
输出:true
解释:如下图所示,只有高亮所示的一个合法环:
示例 3:

输入:grid = [[“a”,“b”,“b”],[“b”,“z”,“b”],[“b”,“b”,“a”]]
输出:false
提示:
- m = g r i d . l e n g t h m = grid.length m=grid.length
- n = g r i d [ i ] . l e n g t h n = grid[i].length n=grid[i].length
- 1 ≤ m ≤ 500 1 \leq m \leq 500 1≤m≤500
- 1 ≤ n ≤ 500 1 \leq n \leq 500 1≤n≤500
- g r i d grid grid 只包含小写英文字母。
解法一:并查集
我们从左上角开始遍历,假设当前位置是 ( i , j ) (i,j) (i,j),我们只用判断它的右边 和 下面的位置即 ( i + 1 , j ) (i+1,j) (i+1,j) 和 ( i , j + 1 ) (i,j + 1) (i,j+1)。
如果 g r i d [ i ] [ j ] = g r i d [ i + 1 ] [ j ] grid[i][j] = grid[i + 1][j] grid[i][j]=grid[i+1][j] :
- g r i d [ i ] [ j ] grid[i][j] grid[i][j] 和 g r i d [ i + 1 ] [ j ] grid[i+1][j] grid[i+1][j] 处于两个连通块,那么我就他们合并到一起;
- 如果 g r i d [ i ] [ j ] grid[i][j] grid[i][j] 和 g r i d [ i + 1 ] [ j ] grid[i+1][j] grid[i+1][j] 已经处于同一个连通块了,那么说明存在环,直接返回
true;
如果 g r i d [ i ] [ j ] = g r i d [ i ] [ j + 1 ] grid[i][j] = grid[i ][j + 1] grid[i][j]=grid[i][j+1] :
- g r i d [ i ] [ j ] grid[i][j] grid[i][j] 和 g r i d [ i ] [ j + 1 ] grid[i][j + 1] grid[i][j+1] 处于两个连通块,那么我就他们合并到一起;
- 如果 g r i d [ i ] [ j ] grid[i][j] grid[i][j] 和 g r i d [ i ] [ j + 1 ] grid[i][j+1] grid[i][j+1] 已经处于同一个连通块了,那么说明存在环,直接返回
true;
时间复杂度: O ( m × n ) O(m \times n) O(m×n)
C++代码:
class Solution {
public:bool containsCycle(vector<vector<char>>& grid) {int m = grid.size() , n = grid[0].size() , len = m * n;vector<int> p(len);for(int i = 0;i < len;i++) p[i] = i;function<int(int)> find = [&](int x) -> int{if(x != p[x]){p[x] = find(p[x]);}return p[x];};auto is_connected = [&](int a,int b){int x = find(a) , y = find(b);if(x == y) return true;return false;};auto merge = [&](int a,int b){int x = find(a) , y = find(b);p[x] = y;};for(int i = 0;i < m;i++){for(int j = 0;j < n;j++){int x = i * n + j , y;if(j + 1 < n && grid[i][j] == grid[i][j + 1]){y = i * n + j + 1;if(is_connected(x,y)) return true;merge(x,y);}if(i + 1 < m && grid[i][j] == grid[i + 1][j]){y = (i + 1) * n + j;if(is_connected(x,y)) return true;merge(x,y);}}}return false;}
};
解法二:dfs
我们每次从没有访问过的位置出发开始超 上下左右 四个方向开始访问。
访问的时候注意,不能沿着来的方向再反方向回去。
在 dfs 的过程中,如果我们访问到了跟当前位置值相同,并且之前访问过的点,就说明存在环,直接返回 true。
否则说明不存在环,最后返回 false。
时间复杂度: O ( m × n ) O(m \times n) O(m×n)
C++代码:
//(-1,0) (0,-1) (0,1) (1,0) 分别为 上左右下
//这样对于 k 那么它的反方向就是 3 - kconst int dx[4] = {-1,0,0,1};
const int dy[4] = {0,-1,1,0};
class Solution {
public:bool containsCycle(vector<vector<char>>& grid) {int m = grid.size() , n = grid[0].size();bool vis[m][n];memset(vis,false,sizeof vis);function<bool(int,int,int)> dfs = [&](int x,int y,int dir) ->bool{for(int k = 0;k < 4;k++){int nx = x + dx[k] , ny = y + dy[k];//dir == k 说明现在的方向 跟 来的时候的方向 相反//我们不能再沿着来的路回去,所以这里直接跳过if(dir == k || nx < 0 || nx >= m || ny < 0 || ny >= n || grid[x][y] != grid[nx][ny]) continue;//此时 (nx,ny) 这个点之前已经访问过了 说明存在环 直接返回trueif(vis[nx][ny]) return true;vis[nx][ny] = true;if(dfs(nx,ny,3 - k)) return true;}return false;};for(int i = 0;i < m;i++){for(int j = 0;j < n;j++){if(vis[i][j]) continue;vis[i][j] = true;if(dfs(i,j,-1)) return true;}}return false;}
};
相关文章:
Leetcode.1559 二维网格图中探测环
题目链接 Leetcode.1559 二维网格图中探测环 rating : 1838 题目描述 给你一个二维字符网格数组 g r i d grid grid ,大小为 m x n ,你需要检查 g r i d grid grid 中是否存在 相同值 形成的环。 一个环是一条开始和结束于同一个格子的长度 大于等于…...
阿拉伯数字转中文数字字符,最高支持千京
直接上代码 UtilityClass public class NumberFormatUtil {/** 中文 -> 数字对应关系 */private static final Map<Character, Integer> DIGIT_CHINA new HashMap<>();/** 数字 -> 中文对应关系 */private static final Map<Integer, Character> DIGI…...
Python基础--序列操作/函数
Python基础 1.序列的操作 2.函数 1. 数据类型的具体操作 1.1 序列操作--列表具体操作: #定义列表 listA [] #定义一个空列表 listB [1,2.8,"你好",listA,[1,2,3]] # 访问列表 print(listB)#查看整个列表 print(listB[2])#查看单个…...
Kafka与Zookeeper版本对应关系
文章目录 了解版本对应Kafka安装包Kafka源码包 了解 比如: kafka_2.11-1.1.1.jar包 其中2.11表示的是Scala的版本,因为Kafka服务器端代码完全由Scala语音编写。”-“后面的1.1.1表示的kafka的版本信息。遵循一个基本原则,Kafka客户端版本和服…...
Arch Linux 使用桥接模式上网
如果我们想要将虚拟机与物理主机同一网段,并且像物理机器一样被其他设备访问,则需要以桥接模式上网,这个时候,物理主机就必须配置为使用网桥上网了。 注意:这里我们使用了 NetworkManager 网络管理工具中的 nmcli 来进…...
Vue 中使用 WebWorker
目录 安装 loader 应用场景 打包时错误处理 安装 loader npm install worker-loader -D 如果直接把worker.js放到public目录下,则不需要安装loader vue.config.js const { defineConfig } require(vue/cli-service)module.exports defineConfig({transpileDe…...
财务管理系统javaweb会计账房进销存jsp源代码mysql
本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 财务管理系统javaweb java,Struts2,bootstrap,mysql,…...
企业服务器被devos勒索病毒攻击后怎么处理,devos勒索病毒如何攻击的
众所周知,科学技术是第一生产力,科学技术的发展给企业与人们的生活带来了极大变化,但随之而来的网络安全威胁也不断增加。最近,我们收到很多企业的求助,企业的计算机服务器遭到了devos勒索病毒的攻击,导致企…...
React源码解析18(2)------ FilberNode,FilberRootNode结构关系
摘要 在上一篇,我们实现了通过JSX转换为ReactElement的方法,也看到了转换后React元素的结构。但是这个React元素,并不能很清楚的表达组件之间的关系,以及属性的处理。 所以在React内部,会将所有的React元素转换为Fil…...
什么是Session?它在SQLAlchemy中扮演什么角色?
让我们先来谈谈什么是“Session”。在你逛超市或者餐厅的时候,你可能会遇到一种叫做“前台”的东西。你知道那是干什么的吗?它是用来暂存你买的东西,这样你就可以从容地结账,而不必抱着满满一购物车的商品。 数据库的“Session”…...
Java 中 Set集合常用方法
.add() 添加元素 对象名.add() 向Set集合中添加元素 (但不能添加重复元素,Set集合中不允许元素重复) Set<String> s new HashSet<String>(); // 添加数据 s.add("aaa"); s.add("bbb"); addAll(Collectio…...
(MVC)SpringBoot+Mybatis+Mapper.xml
前言:本篇博客主要对MVC架构、Mybatis工程加深下理解,前面写过一篇博客:SprintBoothtml/css/jsmybatis的demo,里面涉及到了Mybatis的应用,此篇博客主要介绍一种将sql语句写到了配置文件里的方法,即Mybatis里…...
【Linux命令行与Shell脚本编程】第十九章 正则表达式
Linux命令行与Shell脚本编程 第十九章 正则表达式 文章目录 Linux命令行与Shell脚本编程 第十九章 正则表达式九.正则表达式9.1.正则表达式基础9.1.1.正则表达式的类型9.2.定义BRE模式9.2.1.普通文本9.2.2.特殊字符 9.2.3.锚点字符锚定行首^锚定行尾$组合锚点 9.2.4.点号字符\.…...
vue exceljs 实现导出excel并设置网格线、背景色、 垂直居中、分页打印
一、 下载 exceljs pnpm install exceljs二、 页面中使用 // 导出 exportExcelexportToExcel() {this.$confirm("此操作将导出excel文件, 是否继续?", "提示", {confirmButtonText: "确定",cancelButtonText: "取消",type: "wa…...
TC358774/5显示桥接(MIPI DSI到LVDS)
东芝TC358774/5显示桥针对使用带有MIPI DSI(显示串行接口)连接的主机处理器的手持设备进行了优化。tc358774 /5作为协议桥接,使视频数据流从主机处理器链接到驱动LVDS显示面板。tc358774 /5桥接器可以配置为多达4通道MIPI DSI,每通道数据速率高达1 Gbps&…...
企业内部FAQ常见问题展示分享的价值
企业内部FAQ(常见问题)展示分享是一种将常见问题和解决方案以问答形式呈现给员工的方式。这种方式可以帮助企业提高工作效率、提供一致的解决方案、提升员工满意度和减少重复工作。 企业内部FAQ常见问题展示分享的价值: 1. 提高工作效率 企…...
React 核心开发者 Dan Abramov 宣布从 Meta 离职
导读React.js 核心开发者、Redux 作者 Dan Abramov 在社交平台发文宣布,将辞去在 Meta 的职务: “我感到苦乐参半,几周后我就要辞去 Meta 的工作了。在 Meta 的 React 组织工作是我的荣幸。感谢我过去和现在的同事接纳我,容忍我犯…...
【C/C++】std::vector 优化点(官方同步)
预分配空间:使用 reserve() 方法预分配 vector 的空间,避免频繁的内存分配和拷贝操作。 使用 emplace_back():使用 emplace_back() 方法插入元素,避免了拷贝构造函数的调用,提高了插入效率。 使用移动语义࿱…...
【vue3】elementPlus主题色定制
以scss语言为例 1、element-plus自动按需导入配置,可参考官网按需导入模块 安装element-plus及辅助插件 npm i element-plus --save安装辅助插件 npm install -D unplugin-vue-components unplugin-auto-import安装sass npm i sass -D2、vite.config.js 中配置…...
MATLAB 2023a的机器学习、深度学习
MATLAB 2023版的深度学习工具箱,提供了完整的工具链,使您能够在一个集成的环境中进行深度学习的建模、训练和部署。与Python相比,MATLAB的语法简洁、易于上手,无需繁琐的配置和安装,让您能够更快地实现深度学习的任务。…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...
echarts使用graphic强行给图增加一个边框(边框根据自己的图形大小设置)- 适用于无法使用dom的样式
pdf-lib https://blog.csdn.net/Shi_haoliu/article/details/148157624?spm1001.2014.3001.5501 为了完成在pdf中导出echarts图,如果边框加在dom上面,pdf-lib导出svg的时候并不会导出边框,所以只能在echarts图上面加边框 grid的边框是在图里…...
云原生安全实战:API网关Envoy的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关 作为微服务架构的统一入口,负责路由转发、安全控制、流量管理等核心功能。 2. Envoy 由Lyft开源的高性能云原生…...


