栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

[英雄星球六月集训LeetCode解题日报] 第26日 并查集

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

[英雄星球六月集训LeetCode解题日报] 第26日 并查集

[英雄星球六月集训LeetCode解题日报] 第26日 并查集
    • 日报
    • 题目
      • 一、 1559. 二维网格图中探测环
        • 1. 题目描述
        • 2. 思路分析
        • 3. 代码实现
      • 二、 1391. 检查网格中是否存在有效路径
        • 1. 题目描述
        • 2. 思路分析
        • 3. 代码实现
      • 三、 1202. 交换字符串中的元素
      • 1. 题目描述
        • 2. 思路分析
        • 3. 代码实现

日报
  • 今天的题都比较朴素,并查集的基础应用。
题目 一、 1559. 二维网格图中探测环

链接: 1559. 二维网格图中探测环

1. 题目描述

2. 思路分析
  • 对于网格里每对相邻的格子,如果他们值相同,就可以连接起来。
  • 那么我们朝单方向连接即可:
    • 对于每个格子我们连接它的上方和左方。
    • 不能连右和下的原因是:移到下一个格子的时候会产生重复处理。
3. 代码实现
class UnionFind:
    def __init__(self,size):
        self.fathers = list(range(size))
    def find_father(self,x):
        return self._zip_find_father(x)    
    def _zip_find_father(self,x):
        fathers = self.fathers
        if fathers[x] != x:
            fathers[x] = self._zip_find_father(fathers[x])
        return fathers[x]                      
    def union(self,x,y):
        x = self.find_father(x)
        y = self.find_father(y)
        if x == y:
            return False
        self.fathers[x] = y       
        return True 
class Solution:
    def containsCycle(self, grid: List[List[str]]) -> bool:
        m,n = len(grid),len(grid[0])
        uf = UnionFind(m*n)
        for i in range(m):
            for j in range(n):
                if i > 0:
                    if grid[i][j] == grid[i-1][j] and not uf.union(i*n+j,(i-1)*n+j):
                        return True
                if j > 0:
                    if grid[i][j] == grid[i][j-1] and not uf.union(i*n+j,i*n+j-1):
                        return True
        return False

二、 1391. 检查网格中是否存在有效路径

链接: 1391. 检查网格中是否存在有效路径

1. 题目描述

2. 思路分析

用并查集处理所有网格,最后检查起始点和结束点是否连通即可(祖宗相同)。

  • 这题特殊之处就是要全部特判相邻网格是否连通,v=grid[i][j]:
    • v==1时:它只能左右移动,且向左移动时,左边只能连接1、4、6;向右移动时,右边只能连接1、3、5。
    • v==其它时,均需特判。
    • 为了代码简洁,我们给1-6编号为0-5,用列表储存这6中情况分别对应的方向和方向上能连接的网格值。
    • 然后就是遍历所有网格并且让他们移动,判断移动后的网格符合条件就合并家族即可。
3. 代码实现
class UnionFind:
    def __init__(self,size):
        self.fathers = list(range(size))
    def find_father(self,x):
        return self._zip_find_father(x)    
    def _zip_find_father(self,x):
        fathers = self.fathers
        if fathers[x] != x:
            fathers[x] = self._zip_find_father(fathers[x])
        return fathers[x]                      
    def union(self,x,y):
        x = self.find_father(x)
        y = self.find_father(y)
        if x == y:
            return False
        self.fathers[x] = y       
        return True 
    def is_same_father(self,x,y):
        return self.find_father(x)==self.find_father(y)
class Solution:
    def hasValidPath(self, grid: List[List[int]]) -> bool:
        m,n = len(grid),len(grid[0])
        uf = UnionFind(m*n)
        def in_bound(x,y):
            return 0<=x1,4,6}
        right = {1,3,5}
        top = {2,3,4}
        bottom = {2,5,6}
        dirs = [  # 6个方块分别能走的方向
            [(0,1),(0,-1)],  # 右左
            [(1,0),(-1,0)],  # 下上
            [(0,-1),(1,0)],  # 左下
            [(0,1),(1,0)],   # 右下
            [(-1,0),(0,-1)], # 上左
            [(0,1),(-1,0)],  # 右上
        ]
        accepts = [  # 6个方块按方向走后,能连通的合法块
            [right,left],
            [bottom,top],
            [left,bottom],
            [right,bottom],
            [top,left],
            [right,top],
        ]
        for i in range(m):
            for j in range(n):
                k = grid[i][j] - 1  # 用来索引这个块的属性
                for z in range(2):  # 走他能走的两个方向
                    x,y = i+dirs[k][z][0],j+dirs[k][z][1]
                    accept = accepts[k][z]
                    if in_bound(x,y) and grid[x][y] in accept:
                        uf.union(hashed(i,j),hashed(x,y))

        return uf.is_same_father(hashed(0,0),hashed(m-1,n-1))

三、 1202. 交换字符串中的元素

链接: 1202. 交换字符串中的元素

1. 题目描述

2. 思路分析
  • 我们用并查集把可以互相交换的字符合并为家族。
  • 显然同一家族中的字符可以任意摆放。
  • 那么我们对每个家族内部排序,然后按顺序填回他们家族的位置即可。
  • 为了Python方便比较大小和转换,我先把所有字母变成ASCII码,最后拼接时再转回来。
3. 代码实现
class UnionFind:
    def __init__(self,size):
        self.fathers = list(range(size))
    def find_father(self,x):
        return self._zip_find_father(x)    
    def _zip_find_father(self,x):
        fathers = self.fathers
        if fathers[x] != x:
            fathers[x] = self._zip_find_father(fathers[x])
        return fathers[x]                      
    def union(self,x,y):
        x = self.find_father(x)
        y = self.find_father(y)
        if x == y:
            return False
        self.fathers[x] = y       
        return True 
    def is_same_father(self,x,y):
        return self.find_father(x)==self.find_father(y)
class Solution:
    def smallestStringWithSwaps(self, s: str, pairs: List[List[int]]) -> str:
        ss = [ord(c) for c in s]
        n = len(ss)
        uf = UnionFind(n)
        for a,b in pairs:
            uf.union(a,b)
        familys = defaultdict(list)
        for i in range(n):
            familys[uf.find_father(i)].append(i)
        
        ans = [0]*n
        for ps in familys.values():
            ps2 = sorted(ps,key=lambda x:ss[x])            
            # print (ps,ps2)
            for i in range(len(ps)):
                ans[ps[i]] = ss[ps2[i]] 
        
        return ''.join(chr(c) for c in ans)
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/993838.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号