leetcode1559. 二维网格图中探测环(Python3、c++)

该博客讨论了LeetCode1559题目的解决方案,采用并查集方法查找二维网格图中相同值形成的环。通过将网格视为图,连接相同值的相邻点,若在合并过程中发现已连接形成环,则返回存在环的结果。文章提供了Python3和C++的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

leetcode1559. 二维网格图中探测环

给你一个二维字符网格数组 grid ,大小为 m x n ,你需要检查 grid 中是否存在 相同值 形成的环。

一个环是一条开始和结束于同一个格子的长度 大于等于 4 的路径。对于一个给定的格子,你可以移动到它上、下、左、右四个方向相邻的格子之一,可以移动的前提是这两个格子有 相同的值

同时,你也不能回到上一次移动时所在的格子。比方说,环 (1, 1) -> (1, 2) -> (1, 1) 是不合法的,因为从 (1, 2) 移动到 (1, 1) 回到了上一次移动时的格子。

如果 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 == grid.length
  • n == grid[i].length
  • 1 <= m <= 500
  • 1 <= n <= 500
  • grid 只包含小写英文字母。

方法:并查集

思路:

本题的做法有很多,常见的是DFS和BFS,这里介绍使用并查集的方法。

无论是哪种方法,我们都是将这个grid数组当作图来处理,即两个相邻的,且字母相同的点之间有一条无向路径。

对于并查集来说,如果两个点之间有路径,那么这两个点就应该进行合并。我们**对数组中的某个点,将它与上面和左面两个相邻的点进行比较,如果字母相同,则将两点相连。**之所以不选择对四个方向的相邻点进行合并,是因为如果对上下左右四个点进行比较,那么在遍历到下一个点的时候(比如该点右边的点),该点的左边点即为原来的点,导致重复;对于其他三个方向也构成重复,因此我们只选择两个方向的相邻点,这样每两个相邻点之间都只会处理一次。

下面我们考虑如何判断是环,对于某个点,我们与上面和左面的两个点进行处理,假设这两个中的某个点与该点字母相同,即需要合并,如果进行合并操作时候,发现这两个点的根节点相同,即已经在同一个连通分量了,那么就说明产生了环(因为刚开始每个点都是单独的根节点,通过不断的合并,这两个点都合并到了一个根节点下,再次遍历这个点,肯定产生了环)。

因此,我们构建长度为m * n的并查集,遍历数组中每个点,对它上面和左面两个相邻点进行操作,如果两者字母相等,且不再同一根节点,那么二者合并到一个根节点下;如果二者已经是同一个根节点了,说明遇到了环,直接返回True。遍历结束没有返回的话,返回False,说明没有环,详情见代码。

值得注意的是,二维数组中对应的点,在并查集中为一维数组,因此需要进行转换,对于点(i,j),它在并查集中的位置为i*n+j

代码:

Python3:
class UnionFind:
    #初始化,一共n个节点的并查集
    def __init__(self,n):
        self.parent = [k for k in range(n)]
    #查找某个元素的根节点
    def find(self,index):
        if self.parent[index] == index:
            return index
        #递归进行路径压缩
        self.parent
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值