[Swift]LeetCode130. 被围绕的区域 | Surrounded Regions
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/9963065.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
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 }

浙公网安备 33010602011771号