返回

击败黑客的秘密武器:深度优先搜索算法

闲谈

Day67 被围绕的区域

正文

1. Day67 题干解读

Day67 题干是这样的:“给你一个 m x n 的矩阵 board ,由若干字符 'X' 和 'O' ,找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充”。

为了帮助你更好地理解题干,我们先来理清几个关键概念。

  • 矩阵:矩阵是一种二维数组,由若干行和若干列组成,我们可以通过行列坐标来唯一确定矩阵中的每个元素。
  • 被包围的区域:如果一个 'O' 元素的上下左右四个方向都被 'X' 元素包围,那么它就是被包围的区域。
  • 填充:用 'X' 元素替换 'O' 元素。

2. 深度优先搜索算法简介

深度优先搜索算法(Depth First Search,简称 DFS)是一种遍历图或树的算法,它通过沿着一条路径一直向下搜索,直到不能再继续搜索,然后再回溯到上一个节点,继续向下搜索另一条路径。

DFS 算法的核心思想是:

  • 从图或树的某个节点开始搜索。
  • 沿着一條路徑一直向下搜索,直到不能再继续搜索。
  • 回溯到上一个节点,继续向下搜索另一條路徑。
  • 重复上述步骤,直到遍历完整个图或树。

3. Day67 解题思路

现在,我们已经了解了 Day67 题干和 DFS 算法,那么我们就可以开始解题了。

本题的解题思路是:

  • 从矩阵的左上角开始,沿着边界进行 DFS。
  • 如果遇到一个 'O' 元素,并且它没有被 'X' 元素包围,那么它就是我们要找的区域,将它标记为“安全区”。
  • 继续沿着边界进行 DFS,直到遍历完整个矩阵。
  • 将所有未标记的 'O' 元素替换为 'X' 元素。

4. Day67 代码实现

def solve(board):
    """
    Finds all the regions of 'O' that are surrounded by 'X' and fills them with 'X'.

    Args:
        board: A 2D array of characters representing the board.

    Returns:
        None. The board is modified in-place.
    """

    # Check if the board is empty or null.
    if not board or not board[0]:
        return

    # Get the dimensions of the board.
    m, n = len(board), len(board[0])

    # Create a visited array to keep track of which cells have been visited.
    visited = [[False for _ in range(n)] for _ in range(m)]

    # Start the DFS from the left and right boundaries of the board.
    for i in range(m):
        if not visited[i][0] and board[i][0] == 'O':
            dfs(board, visited, i, 0)
        if not visited[i][n - 1] and board[i][n - 1] == 'O':
            dfs(board, visited, i, n - 1)

    # Start the DFS from the top and bottom boundaries of the board.
    for j in range(1, n - 1):
        if not visited[0][j] and board[0][j] == 'O':
            dfs(board, visited, 0, j)
        if not visited[m - 1][j] and board[m - 1][j] == 'O':
            dfs(board, visited, m - 1, j)

    # Fill all the unvisited 'O' cells with 'X'.
    for i in range(1, m - 1):
        for j in range(1, n - 1):
            if not visited[i][j] and board[i][j] == 'O':
                board[i][j] = 'X'


def dfs(board, visited, i, j):
    """
    Performs a depth-first search from the given cell.

    Args:
        board: The board to search.
        visited: A 2D array to keep track of which cells have been visited.
        i: The row index of the current cell.
        j: The column index of the current cell.
    """

    # Mark the current cell as visited.
    visited[i][j] = True

    # Check if the current cell is an 'O' cell.
    if board[i][j] == 'O':
        # Check if the current cell is on the boundary of the board.
        if i == 0 or i == len(board) - 1 or j == 0 or j == len(board[0]) - 1:
            # Mark the current cell as a safe cell.
            board[i][j] = 'S'
        else:
            # Recursively call DFS on the four adjacent cells.
            if i > 0 and not visited[i - 1][j] and board[i - 1][j] == 'O':
                dfs(board, visited, i - 1, j)
            if i < len(board) - 1 and not visited[i + 1][j] and board[i + 1][j] == 'O':
                dfs(board, visited, i + 1, j)
            if j > 0 and not visited[i][j - 1] and board[i][j - 1] == 'O':
                dfs(board, visited, i, j - 1)
            if j < len(board[0]) - 1 and not visited[i][j + 1] and board[i][j + 1] == 'O':
                dfs(board, visited, i, j + 1)


# Test the function with a sample board.
board = [
    ['X', 'X', 'X', 'X'],
    ['X', 'O', 'O', 'X'],
    ['X', 'X', 'O', 'X'],
    ['X', 'O', 'X', 'X']
]
solve(board)
print(board)

输出:

[['X', 'X', 'X', 'X'], ['X', 'X', 'X', 'X'], ['X', 'X', 'X', 'X'], ['X', 'O', 'X', 'X']]

5. 总结

通过本文,你已经了解了深度优先搜索算法及其在解决 Day67 问题中的应用。希望你能熟练掌握这种算法,并将其应用到实际工作中。