zoukankan      html  css  js  c++  java
  • [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 }
  • 相关阅读:
    Ubuntu根底入门教程
    Debian发行版总结
    ARCH中KDEMOD下如何管理挂在NTFS分区乱码的标题问题
    让YUM窗口化
    操持SUSE Linux 10下无法显示阻碍一例
    让debian支撑鼠标中键
    电视片头后期合成软件、制作流程与技巧简介
    关于动态数组、静态数组转换为字符串的一些问题 给 "厨师" 的回复
    论证 Assigned(btn) 与 Assigned(@btn) 的区别 答复 "sunnet"
    WinAPI: GetRegionData
  • 原文地址:https://www.cnblogs.com/strengthen/p/9963065.html
Copyright © 2011-2022 走看看