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的语法简洁、易于上手,无需繁琐的配置和安装,让您能够更快地实现深度学习的任务。…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
Android写一个捕获全局异常的工具类
项目开发和实际运行过程中难免会遇到异常发生,系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler,它是Thread的子类(就是package java.lang;里线程的Thread)。本文将利用它将设备信息、报错信息以及错误的发生时间都…...
算术操作符与类型转换:从基础到精通
目录 前言:从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符:、-、*、/、% 赋值操作符:和复合赋值 单⽬操作符:、--、、- 前言:从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...
【实施指南】Android客户端HTTPS双向认证实施指南
🔐 一、所需准备材料 证书文件(6类核心文件) 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...
【若依】框架项目部署笔记
参考【SpringBoot】【Vue】项目部署_no main manifest attribute, in springboot-0.0.1-sn-CSDN博客 多一个redis安装 准备工作: 压缩包下载:http://download.redis.io/releases 1. 上传压缩包,并进入压缩包所在目录,解压到目标…...


