[leetcode] 959. Regions Cut By Slashes

Description

In a N x N grid composed of 1 x 1 squares, each 1 x 1 square consists of a /, , or blank space. These characters divide the square into contiguous regions.

(Note that backslash characters are escaped, so a \ is represented as “\”.)

Return the number of regions.

Example 1:

Input:
[
  " /",
  "/ "
]
Output: 2

Example 2:

Input:
[
  " /",
  "  "
]
Output: 1

Example 3:

Input:
[
  "\\/",
  "/\\"
]
Output: 4
Explanation: (Recall that because \ characters are escaped, "\\/" refers to \/, and "/\\" refers to /\.)

Example 4:

Input:
[
  "/\\",
  "\\/"
]
Output: 5
Explanation: (Recall that because \ characters are escaped, "/\\" refers to /\, and "\\/" refers to \/.)

Example 5:

Input:
[
  "//",
  "/ "
]
Output: 3

Note:

  1. 1 <= grid.length == grid[0].length <= 30
  2. grid[i][j] is either ‘/’, ‘’, or ’ '.

分析

题目的意思是:把一个N*N的网格用斜线分开,问最终的连通区域有多少个。这道题我参考了一下别人的思路.

  • 区域连接求数量的问题用并查集解决
  • 大方块由N * N的个小方块组成,将小方块按照双线划分顺时针分为0,1,2,3 共4个区域,总共的区域数为4NN
  • 并且小方块之间是两两连接的 ,左方块的 2区域 与 右方块的 1区域连接,上方块的 3区域 与 下方块的 0 区域连接
  • 当‘/’时,小方块的 0,1 区域连接, 2,3区域连接
  • 当‘\’时 ,小方块的 0,2区域连接,1,3区域连接
  • 求区域个数实际是求有多少颗树

我这里给了一张图,可以对照图进行理解

在这里插入图片描述

代码

class DSU:
    def __init__(self,n):
        self.p=list(range(n))
        
    def find(self,x):
        if(self.p[x]!=x):
            self.p[x]=self.find(self.p[x])
        return self.p[x]
    
    def union(self,x,y):
        xr=self.find(x)
        yr=self.find(y)
        self.p[xr]=yr
        
class Solution:
    def regionsBySlashes(self, grid: List[str]) -> int:
        n=len(grid)
        dsu=DSU(4*n*n) # 总共有 4n * n 个 小区域块
        for i in range(n):
            for j in range(n):
                root=4*(i*n+j)
                if(grid[i][j] in '/ '): # 将本格子的左边、上边合并;右边、下边合并;
                    dsu.union(root+0,root+1) 
                    dsu.union(root+2,root+3)
                if(grid[i][j] in '\ '): # 将本格子的上边、右边合并;左边、下边合并;
                    dsu.union(root+0,root+2)
                    dsu.union(root+1,root+3)
                  
                if(i+1<n):
                    dsu.union(root+3,root+4*n+0) # 将本格子的下边与下一行格子的上边合并
                if(i-1>=0):
                    dsu.union(root+0,root-4*n+3) # 将本格子的上边与上一行格子的下边合并
                if(j+1<n):
                    dsu.union(root+2,root+4+1) # 将本格子的右边与右边格子的左边合并
                if(j-1>=0):
                    dsu.union(root+1,root-4+2) # 将本格子的左边与左边格子的右边合并
        res=0   
        # 取出index = parent[index] 的节点即可 即算出有多少颗树就是有多少个区域
        for i in range(4*n*n):
            if(dsu.find(i)==i):
                   res+=1
        return res

参考文献

solution
Union-Find算法详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

农民小飞侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值