LeetCode 130. Surrounded Regions - 彻底掌握并查集(Union Find)系列题13

该博客探讨了LeetCode 130题,即如何找到并包围4方向连接的区域。通过使用并查集(Union Find)算法,确定并标记出所有封闭的'O'区域,最终将这些封闭区域的'O'替换为'X'。题目与LeetCode 1254题相似,都是寻找并处理封闭的岛屿问题。

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

Given an m x n matrix board containing 'X' and 'O'capture all regions that are 4-directionally surrounded by 'X'.

A region is captured by flipping all 'O's into 'X's in that surrounded region.

Example 1:

Input: board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]
Output: [["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]]
Explanation: Surrounded regions should not be on the border, which means that any 'O' on the border of the board are not flipped to 'X'. Any 'O' that is not on the border and it is not connected to an 'O' on the border will be flipped to 'X'. Two cells are connected if they are adjacent cells connected horizontally or vertically.

Example 2:

Input: board = [["X"]]
Output: [["X"]]

Constraints:

  • m == board.length
  • n == board[i].length
  • 1 <= m, n <= 200
  • board[i][j] is 'X' or 'O'.

跟求封闭岛屿题 Leetcode1254. Number of Closed Islands 基本上一样。先用并查集(Union Find)合并所有相连的‘O’的集合,同时标注‘O’集合是否为封闭的。最后遍历一遍矩阵把属于封闭集合的‘O’改成‘X’。具体分析可以参考 Leetcode1254. Number of Closed Islands

class UnionFind :
    def __init__(self, n) :
        self.parent = [-1] * n
        self.size = [0] * n
        self.isClosed = [False] * n  #记录所在岛屿是否封闭
        
    def find(self, x) :        
        if self.parent[x] != x :
            self.parent[x] = self.find(self.parent[x])
        return self.parent[x]
    
    def merge(self, x, y) :
        px, py = self.find(x), self.find(y)
        #两个同属一个岛屿直接返回,否则进行合并
        if px == py :
            return
        
        #小岛合并到大岛,为了提高查找的效率
        if self.size[px] > self.size[py] :
            self.parent[py] = px
            self.size[px] += self.size[py]
            self.isClosed[px] &= self.isClosed[py] 
        else :
            self.parent[px] = py
            self.size[py] += self.size[px]
            self.isClosed[py] &= self.isClosed[px]

        
    #每增加一新陆地需要进行更新parent
    def updateParent(self, x, closed) :
        if self.parent[x] == -1 :
            self.parent[x] = x
            self.size[x] = 1
            self.isClosed[x] = closed

class Solution:
    def solve(self, board: List[List[str]]) -> None:
        m, n = len(board), len(board[0])
        
        uf = UnionFind(m * n)
  
        for i in range(m) :
            for j in range(n) :
                if board[i][j] == 'O' :
                    close = True if (i > 0 and i < m - 1 and j > 0 and j < n - 1 ) else False
                    uf.updateParent(i * n + j, close)
                    if i - 1 >= 0 and board[i - 1][j] == 'O' :
                        uf.merge(i * n + j, (i - 1) * n + j )
                    if j - 1 >= 0 and board[i][j - 1] == 'O' :
                        uf.merge(i * n + j, i * n + j - 1)
    
        for i in range(m) :
            for j in range(n) :
                if board[i][j] == 'O' and uf.isClosed[uf.find(i * n + j)] == True:
                    board[i][j] = 'X'

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值