日月换新天。为有牺牲多壮志,敢教

[Swift]LeetCode130. 被围绕的区域 | Surrounded Regions

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/9963065.html 
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'.

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

Example:

X X X X
X O O X
X X O X
X O X X

After running your function, the board should be:

X X X X
X X X X
X X X X
X O X X

Explanation:

Surrounded regions shouldn’t 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.


 给定一个二维的矩阵,包含 'X' 和 'O'(字母 O)。

找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。

示例:

X X X X
X O O X
X X O X
X O X X

运行你的函数后,矩阵变为:

X X X X
X X X X
X X X X
X O X X

解释:

被围绕的区间不会存在于边界上,换句话说,任何边界上的 'O' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都会被填充为 'X'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。


52ms

复制代码
 1 class Solution {
 2     func solve(_ board: inout [[Character]]) {
 3         let h = board.count
 4         guard h > 2 else { return }
 5         
 6         let w = board[0].count
 7         guard w > 2 else { return }
 8         
 9         for i in 0..<h {
10             mark(&board, i, 0)
11             mark(&board, i, w - 1)
12         }
13         
14         for j in 0..<w {
15             mark(&board, 0, j)
16             mark(&board, h - 1, j)
17         }
18         
19         for i in 0..<h {
20             for j in 0..<w {
21                 if board[i][j] == "O" {
22                    board[i][j] = "X"
23                 } else if board[i][j] == "T" {
24                    board[i][j] = "O"
25                 }
26             }
27         }
28     }
29     
30     func mark(_ board: inout [[Character]], _ i: Int, _ j: Int) {
31         guard i >= 0 && i < board.count else { return }
32         guard j >= 0 && j < board[i].count else { return }
33         guard board[i][j] == "O" else { return }
34         
35         board[i][j] = "T"
36         
37         mark(&board, i - 1, j)
38         mark(&board, i + 1, j)
39         mark(&board, i, j - 1)
40         mark(&board, i, j + 1)
41     }
42 }
复制代码

56ms

复制代码
 1 class Solution {
 2     func solve(_ board: inout [[Character]]) {
 3         for i in 0..<board.count {
 4             for j in 0..<board[i].count {
 5                 if (i == 0 || i == board.count - 1 || j == 0 || j == board[i].count - 1) && board[i][j] == "O" {
 6                     dfs(&board, i, j)
 7                 }
 8 
 9             }
10         }
11         for i in 0..<board.count {
12             for j in 0..<board[i].count {
13                 if board[i][j] == "O" {
14                     board[i][j] = "X"
15                 }
16                 if board[i][j] == "Y" {
17                     board[i][j] = "O"
18                 }
19             }
20         }
21     }
22     private func dfs(_ board: inout [[Character]], _ i: Int, _ j: Int) {
23         if board[i][j] == "O" {
24 
25             board[i][j] = "Y"
26             if i > 0 && board[i - 1][j] == "O" {
27                 dfs(&board, i - 1, j)
28             }
29 
30             if j < board[i].count - 1 && board[i][j + 1] == "O" {
31                 dfs(&board, i, j + 1)
32             }
33 
34             if i < board.count - 1 && board[i + 1][j] == "O" {
35                 dfs(&board, i + 1, j)
36             }
37 
38             if j > 0 && board[i][j - 1] == "O" {
39                 dfs(&board, i, j - 1)
40             }
41         }
42     }
43 }
复制代码

60ms

复制代码
 1 class Solution {
 2     func solve(_ board: inout [[Character]]) {
 3         guard board.count > 0 && board[0].count > 0 else {
 4             return
 5         }
 6         
 7         let countRow = board.count - 1
 8         let countCol = board[0].count - 1
 9         
10         var visited = [[Bool]](repeating:[Bool](repeating: false, count: countCol+1), count: countRow+1)
11         var boarder0Indexs = [(Int,Int)]()
12         
13         let direction  = [(-1,0),(1,0),(0,-1),(0,1)] // top bot left right
14         
15         for row in 0...countRow {
16             for col in 0...countCol {
17                 if row == 0 || col == 0 || row == countRow || col == countCol {
18                     if board[row][col] == "O" {
19                         board[row][col] = "B"
20                         boarder0Indexs.append((row,col))
21                     }                    
22                 }
23             }
24         }
25         
26         for item in boarder0Indexs {
27             let row = item.0
28             let col = item.1
29              
30             var tempQueue = [(Int,Int)]()
31             tempQueue.append(item)
32             
33             //bfs
34             while (!tempQueue.isEmpty) {
35                 let count = tempQueue.count
36                 for _ in 0..<count {
37                     let curItem = tempQueue.removeFirst()
38                     let curRow = curItem.0
39                     let curCol = curItem.1
40                     //check adjacent cells 
41                     for dirt in direction {
42                         let nextLevelRow = curRow + dirt.0
43                         let nextLevelCol = curCol + dirt.1  
44                         //make sure not out of bounce
45                         if nextLevelRow <= countRow && nextLevelRow >= 0 && nextLevelCol <= countCol && nextLevelCol >= 0 {
46                             if !visited[nextLevelRow][nextLevelCol] {
47                                 if board[nextLevelRow][nextLevelCol] == "O" {
48                                     board[nextLevelRow][nextLevelCol] = "B"
49                                     tempQueue.append((nextLevelRow,nextLevelCol))
50                                 } 
51                                 visited[nextLevelRow][nextLevelCol] = true
52                             }   
53                         }                       
54                     }
55                 }
56             }       
57         }
58         for i in 0...countRow {
59             for j in 0...countCol {
60                 if  board[i][j] == "B" {
61                     board[i][j] = "O"
62                 } else if board[i][j] == "O" {
63                     board[i][j] = "X"
64                 }
65             }
66         }
67     }
68 }
复制代码

80ms

复制代码
 1 class Solution {
 2     func solve(_ board: inout [[Character]]) {
 3         for i in 0..<board.count{
 4             for j in 0..<board[0].count{
 5                 if (i==0 || i == board.count - 1 || j == 0 || j == board[0].count - 1) && board[i][j] == "O" {
 6                     board[i][j] = "M"
 7                     connected(i, j, &board)
 8                 }
 9             }
10         }
11         for i in 0..<board.count{
12             for j in 0..<board[0].count{
13                 if board[i][j] == "O" {
14                     board[i][j] = "X"
15                 }
16                 else if board[i][j] == "M" {
17                     board[i][j] = "O"
18                 }    
19             }
20         }
21     }
22     private func connected(_ i : Int, _ j : Int, _ board: inout [[Character]]){
23         if i-1 > 0 && board[i-1][j] == "O" {
24             board[i-1][j] = "M"
25             connected(i-1, j, &board)
26         }
27         if i+1 < board.count-1 && board[i+1][j] == "O" {
28             board[i+1][j] = "M"
29             connected(i+1, j, &board)
30         }
31         if j-1 > 0 && board[i][j-1] == "O" {
32             board[i][j-1] = "M"
33             connected(i, j-1, &board)
34         }
35         if j+1 < board[i].count-1 && board[i][j+1] == "O" {
36             board[i][j+1] = "M"
37             connected(i, j+1, &board)
38         }
39     }
40 }
复制代码

176ms

复制代码
  1 let X = Character("X")
  2 let O = Character("O")
  3 
  4 class Solution {
  5 
  6     func solve(_ board: inout [[Character]]) {
  7         guard let columnCount = board.first?.count else {
  8             return
  9         }
 10         let rowCount = board.count
 11         let uf = UnionFind(rowCount: rowCount, columnCount: columnCount)
 12 
 13         board.enumerated().forEach { i, row in
 14             row.enumerated().forEach { j, item in
 15                 guard item == O else {
 16                     return
 17                 }
 18 
 19                 if i == 0 || i == rowCount - 1 || j == 0 || j == columnCount - 1 {
 20                     uf.open(i, j)
 21                 }
 22 
 23                 // top
 24                 if i > 0 && board[i - 1][j] == O {
 25                     uf.union(i, j, i - 1, j)
 26                 }
 27 
 28                 // bottom
 29                 if i < rowCount - 1 && board[i + 1][j] == O {
 30                     uf.union(i, j, i + 1, j)
 31                 }
 32 
 33                 // left
 34                 if j > 0 && board[i][j - 1] == O {
 35                     uf.union(i, j, i, j - 1)
 36                 }
 37 
 38                 // right
 39                 if j < columnCount - 1 && board[i][j + 1] == O {
 40                     uf.union(i, j, i, j + 1)
 41                 }
 42             }
 43         }
 44 
 45         for i in 0..<rowCount {
 46             for j in 0..<columnCount where board[i][j] == O {
 47                 if !uf.isOpen(i, j) {
 48                     board[i][j] = X
 49                 }
 50             }
 51         }
 52     }
 53 
 54 }
 55 
 56 class UnionFind {
 57 
 58     var parent: [Int]
 59     var sizes: [Int]
 60 
 61     private let rowCount: Int
 62     private let columnCount: Int
 63 
 64     private var opened: [Bool]
 65 
 66     init(rowCount: Int, columnCount: Int) {
 67         self.rowCount = rowCount
 68         self.columnCount = columnCount
 69 
 70         let count = rowCount * columnCount
 71 
 72         sizes = Array(repeating: 1, count: count)
 73         parent = Array(repeating: 0, count: count)
 74         opened = Array(repeating: false, count: count)
 75 
 76         for i in 0..<count {
 77             parent[i] = i
 78         }
 79     }
 80 
 81     func isOpen(_ i: Int, _ j: Int) -> Bool {
 82         return opened[find(i, j)]
 83     }
 84 
 85     func open(_ i: Int, _ j: Int) {
 86         let index = calculateIndex(i, j)
 87         opened[index] = true
 88     }
 89 
 90     func union(_ li: Int, _ lj: Int, _ ri: Int, _ rj: Int) {
 91         let rootLeft = find(li, lj)
 92         let rootRight = find(ri, rj)
 93 
 94         if li == 0 || li == rowCount - 1 || lj == 0 || lj == columnCount - 1 {
 95             open(li, lj)
 96         }
 97         if ri == 0 || ri == rowCount - 1 || rj == 0 || rj == columnCount - 1 {
 98             open(ri, rj)
 99         }
100 
101         if rootLeft == rootRight {
102             return
103         }
104 
105         if opened[rootLeft] {
106             parent[rootRight] = parent[rootLeft]
107             sizes[rootLeft] += sizes[rootRight]
108             return
109         }
110         if opened[rootRight] {
111             parent[rootLeft] = parent[rootRight]
112             sizes[rootRight] += sizes[rootLeft]
113             return
114         }
115 
116         if sizes[rootLeft] > sizes[rootRight] {
117             parent[rootRight] = parent[rootLeft]
118             sizes[rootLeft] += sizes[rootRight]
119         } else {
120             parent[rootLeft] = parent[rootRight]
121             sizes[rootRight] += sizes[rootLeft]
122         }
123     }
124 
125     func find(_ i: Int, _ j: Int) -> Int {
126         var index = calculateIndex(i, j)
127         while index != parent[index] {
128             parent[index] = parent[parent[index]]
129             index = parent[index]
130         }
131         return index
132     }
133 
134     private func calculateIndex(_ i: Int, _ j: Int) -> Int {
135         return i * columnCount + j
136     }
137 }
复制代码

316ms

复制代码
 1 class Solution {
 2     func solve(_ board: inout [[Character]]) {
 3         for i in 0..<board.count
 4         {
 5             for j in 0..<board[i].count
 6             {
 7                 if (i == 0 || i == board.count - 1 || j == 0 || j == board[i].count - 1) && board[i][j] == "O"
 8                 {
 9                     solveDFS(&board, i, j)
10                 }
11             }
12         }
13         for i in 0..<board.count
14         {
15             for j in 0..<board[i].count
16             {
17                 if board[i][j] == "O" {board[i][j] = "X"}
18                 if board[i][j] == "$" {board[i][j] = "O"}
19             }
20         }
21     }
22     
23     func solveDFS(_ board: inout [[Character]],_ i:Int,_ j:Int)
24     {
25         if board[i][j] == "O"
26         {
27             board[i][j] = "$"
28             if i > 0 && board[i - 1][j] == "O"
29             {
30                 solveDFS(&board, i - 1, j)
31             }
32             if j < board[i].count - 1 && board[i][j + 1] == "O"
33             {
34                 solveDFS(&board, i, j + 1)
35             }
36             if i < board.count - 1 && board[i + 1][j] == "O"
37             {
38                 solveDFS(&board, i + 1, j)
39             }
40             if j > 1 && board[i][j - 1] == "O"
41             {
42                 solveDFS(&board, i, j - 1)
43             }
44         }
45     }
46 }
复制代码

 

posted @   为敢技术  阅读(345)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示
哥伦布
09:09发布
哥伦布
09:09发布
3°
多云
东南风
3级
空气质量
相对湿度
47%
今天
中雨
3°/15°
周三
中雨
3°/13°
周四
小雪
-1°/6°