ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【并查集】leetcode1034.边界着色

2021-12-07 18:33:20  阅读:123  来源: 互联网

标签:int res self 查集 leetcode1034 着色 grid col row


题目:
给你一个大小为 m x n 的整数矩阵 grid ,表示一个网格。另给你三个整数 row、col 和 color 。网格中的每个值表示该位置处的网格块的颜色。

  • 当两个网格块的颜色相同,而且在四个方向中任意一个方向上相邻时,它们属于同一 连通分量 。
  • 连通分量的边界 是指连通分量中的所有与不在分量中的网格块相邻(四个方向上)的所有网格块,或者在网格的边界上(第一行/列或最后一行/列)的所有网格块。

请你使用指定颜色 color 为所有包含网格块 grid[row][col] 的 连通分量的边界 进行着色,并返回最终的网格 grid 。
在这里插入图片描述

解答:

方法一:并查集

1.确定跟grid[row][col]颜色相同的连通块;(体现在 并查集中根节点相同)
2.对连通分量的色块进行上色,上色有两种情况:(1)该色块在矩阵边界上;(2)该色块是连通分量边界,即该色块上下左右相邻色块至少有一个不属于(row, col)的连通分量。

class UF:
    def __init__(self, M):
        self.parent = {}
        # 初始化 parent 
        for i in range(M):
            self.parent[i] = i
    
    #判断x所属集合
    def find(self, x):
        while x!=self.parent[x]:
            x=self.parent[x]
        return x
    
    #合并p和q所在的集合 
    def union(self, p, q):
        if self.connected(p, q): 
            return
        proot = self.find(p)
        qroot = self.find(q)
        self.parent[qroot] = proot

        
    #判断两元素是否属于同一集合     
    def connected(self, p, q):
        return self.find(p) == self.find(q)



class Solution:
    def colorBorder(self, grid: List[List[int]], row: int, col: int, color: int) -> List[List[int]]:
        m=len(grid)
        n=len(grid[0])
        uf=UF(m*n)
        
        #颜色相同且相邻,则对其进行合并
        for i in range(m):
            for j in range(n):
                #上
                if i>0 and grid[i-1][j]==grid[i][j]:
                    uf.union((i-1)*n+j,i*n+j)
                #左
                if j>0 and grid[i][j-1]==grid[i][j]:
                    uf.union(i*n+j-1,i*n+j)
      
        for i in range(m):
            for j in range(n):
                #是否跟grid[row][col]属于同一连通分量
                target=row*n+col
                if uf.connected(i*n+j,target):
                    #是不是位于 矩阵边界
                    if i==0 or i==m-1 or j==0 or j==n-1:
                        grid[i][j]=color
                        continue
                 
                    #是不是位于 连通分量边界,看【上下左右】是不是 不属于该连通分量
                    up=(i-1)*n+j
                    down=(i+1)*n+j
                    left=i*n+j-1
                    right=i*n+j+1
                    if (not uf.connected(up,target))  or (not uf.connected(down,target)) or (not uf.connected(left,target)) or (not uf.connected(right,target)):
                        grid[i][j]=color
        return grid

方法二:BFS
同一「连通分量」的「非边界」格子满足:当前格子的四个方向均存在相邻格子,且当前格子与四个相邻格子颜色一致。

  • 构造res矩阵作为答案,并将其元素初始化为0(若BFS结束,元素依旧为0,则其未被处理)
  • 将(row,col)入队,每次从队列中取出元素,进行四个方位的拓展。拓展时,拓展格子必须与(row,col)位置的元素值相等。
  • 记录当前出队元素是否为边界格子,若为边界格子则对其进行上色。
  • 结束后,遍历res矩阵,恢复未处理元素的原始色。若res[i][j]=0,则令res[i][j]=grid[i][j]

class Solution:
    def colorBorder(self, grid: List[List[int]], row: int, col: int, color: int) -> List[List[int]]:
        #BFS
        m=len(grid)
        n=len(grid[0])
        #res:重判矩阵(通过判断元素是否为0来得知:是否被处理)
        res=[[0]*n for _ in range(m)]
        #dirs:记录方向,分别代表上下左右
        dirs=[(-1,0),(1,0),(0,-1),(0,1)]
        q=collections.deque()
        q.append([row,col])
        while q:
            #print(q)
            curx,cury=q.popleft()
            count=0
            for d in dirs:
                nx=curx+d[0]
                ny=cury+d[1]
                #print(nx,ny)
                if nx<0 or nx>=m or ny<0 or ny>=n:
                    continue
                if grid[nx][ny]!=grid[curx][cury]:
                    continue
                else:
                    count+=1
                #若当前元素已被处理过
                if res[nx][ny]!=0:
                    continue
                q.append([nx,ny])
            #print(count)
            #若当前元素(curx,cury)四个方位皆存在,且与其颜色相同,则当前元素为连通分量的中间元素
            if count==4:
                #恢复原始色
                res[curx][cury]=grid[curx][cury]
            else:
                res[curx][cury]=color
            #print(res)

        #恢复未处理元素的原始色
        for i in range(m):
            for j in range(n):
                if res[i][j]==0:
                    res[i][j]=grid[i][j]
        
        return res

方法三:DFS

标签:int,res,self,查集,leetcode1034,着色,grid,col,row
来源: https://blog.csdn.net/jqq125/article/details/121771771

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有