【LeetCode】130.被围绕的区域

leetcode

 

核心思路

本题的核心目标是捕获矩阵中所有被 'X' 围绕的 'O' 区域并将其替换为 'X'。我们可以采用逆向思维,因为位于矩阵边缘的 'O' 及其相连的 'O' 区域不会被围绕,所以我们先找出这些不会被围绕的 'O' 区域,将其标记为其他字符(如 '#'),然后遍历整个矩阵,把剩下的 'O' 替换为 'X',最后再把标记为 '#' 的字符还原为 'O'。

 

关键步骤

  1. 边界检查:首先检查矩阵是否为空或者行数、列数小于等于 2,如果是则直接返回,因为这种情况下不存在被围绕的区域。
  2. 标记边缘 'O' 及其相连区域
    • 遍历矩阵的上下边界,对于边界上的 'O',使用深度优先搜索(DFS)或广度优先搜索(BFS)将其相连的 'O' 区域标记为 '#'。
    • 遍历矩阵的左右边界,同样对边界上的 'O' 及其相连区域进行标记。
  3. 替换剩余 'O' 为 'X':再次遍历整个矩阵,将所有未被标记的 'O' 替换为 'X'。
  4. 还原标记的 '#' 为 'O':最后将所有标记为 '#' 的字符还原为 'O'。

 

代码实现

package main

import "fmt"

// solve 函数用于捕获被围绕的区域
func solve(board [][]byte) {
    if len(board) == 0 || len(board[0]) == 0 {
        return
    }
    m, n := len(board), len(board[0])
    // 标记边缘 'O' 及其相连区域
    for i := 0; i < m; i++ {
        dfs(board, i, 0)
        dfs(board, i, n-1)
    }
    for j := 0; j < n; j++ {
        dfs(board, 0, j)
        dfs(board, m-1, j)
    }
    // 替换剩余 'O' 为 'X',还原 '#' 为 'O'
    for i := 0; i < m; i++ {
        for j := 0; j < n; j++ {
            if board[i][j] == 'O' {
                board[i][j] = 'X'
            } else if board[i][j] == '#' {
                board[i][j] = 'O'
            }
        }
    }
}

// dfs 函数用于深度优先搜索标记相连的 'O' 区域
func dfs(board [][]byte, i, j int) {
    m, n := len(board), len(board[0])
    if i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'O' {
        return
    }
    board[i][j] = '#'
    dfs(board, i+1, j)
    dfs(board, i-1, j)
    dfs(board, i, j+1)
    dfs(board, i, j-1)
}

 

 

复杂度分析

  • 时间复杂度\(O(m \times n)\),其中 m 是矩阵的行数,n 是矩阵的列数。我们需要遍历矩阵三次,每次遍历的时间复杂度都是 \(O(m \times n)\)。
  • 空间复杂度\(O(m \times n)\),主要是递归调用栈的空间开销。在最坏情况下,整个矩阵都是 'O',递归深度可能达到 \(m \times n\)。

 

示例解析

对于输入 board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]
  1. 标记边缘 'O' 及其相连区域
    • 矩阵的上下左右边界中,第四行第二列的 'O' 位于边缘,从该 'O' 开始进行深度优先搜索,将其相连的 'O' 标记为 '#'。此时矩阵变为:
[["X","X","X","X"],
["X","O","O","X"],
["X","X","O","X"],
["X","#","X","X"]]
  1. 替换剩余 'O' 为 'X':将未被标记的 'O' 替换为 'X',矩阵变为:
[["X","X","X","X"],
["X","X","X","X"],
["X","X","X","X"],
["X","#","X","X"]]
  1. 还原标记的 '#' 为 'O':将标记为 '#' 的字符还原为 'O',最终矩阵变为:
[["X","X","X","X"],
["X","X","X","X"],
["X","X","X","X"],
["X","O","X","X"]]

 

代码调用示例

func main() {
    board := [][]byte{
        {'X', 'X', 'X', 'X'},
        {'X', 'O', 'O', 'X'},
        {'X', 'X', 'O', 'X'},
        {'X', 'O', 'X', 'X'},
    }
    solve(board)
    for _, row := range board {
        fmt.Println(string(row))
    }
}

 

posted @ 2025-03-11 17:03  云隙之间  阅读(12)  评论(0)    收藏  举报