返回

掌握标记法,解决 LeetCode 2257 难题:计算网格中未被守护的单元格数量

后端

前言

在计算机科学领域,算法和数据结构是解决各种问题的重要工具。算法是指解决特定问题的步骤或方法,而数据结构是指组织和存储数据的方式。二者紧密结合,共同构建了计算机科学的基础。

在众多算法和数据结构中,标记法(Marking Algorithm)是一种简单而有效的技术,常用于解决各种问题。标记法的核心思想是,通过标记或标识某些元素来帮助算法更有效地进行搜索或处理。

LeetCode 2257 题目简介

LeetCode 2257 是一道难度为中等、考察标记法应用的编程题。题目如下:

给定一个 RC 列的网格,其中每个单元格要么是空('.'),要么被守护('#')。一个单元格被守护意味着,它以及上下左右相邻的单元格都被守护。

输入:RC 列的网格,其中每个单元格要么是空('.'),要么被守护('#')。
输出:网格中未被守护的单元格数量。

算法设计与实现

为了解决 LeetCode 2257 问题,我们可以使用标记法来标记已被守护的单元格。具体步骤如下:

  1. 遍历网格,对于每个单元格,检查其上下左右相邻的单元格是否都被守护。如果是,则标记该单元格已被守护。
  2. 再次遍历网格,计算未被守护的单元格数量。

以下 Python 代码实现了上述算法:

def countUnguarded(grid):
    # 标记已被守护的单元格
    def markGuarded(grid, row, col):
        if row < 0 or row >= len(grid) or col < 0 or col >= len(grid[0]) or grid[row][col] == '#' or (row, col) in visited:
            return
        visited.add((row, col))
        markGuarded(grid, row - 1, col)
        markGuarded(grid, row + 1, col)
        markGuarded(grid, row, col - 1)
        markGuarded(grid, row, col + 1)

    # 计算未被守护的单元格数量
    def countUnguarded():
        cnt = 0
        for row in range(len(grid)):
            for col in range(len(grid[0])):
                if (row, col) not in visited:
                    cnt += 1
        return cnt

    visited = set()
    for row in range(len(grid)):
        for col in range(len(grid[0])):
            if grid[row][col] == '#':
                markGuarded(grid, row, col)

    return countUnguarded()

# 测试代码
grid = [['.', '.', '.', '.', '.', '.', '.'],
       ['.', '#', '.', '#', '.', '.', '.'],
       ['.', '.', '.', '.', '.', '.', '.'],
       ['.', '#', '.', '#', '.', '.', '.'],
       ['.', '.', '.', '.', '.', '.', '.']]
print(countUnguarded(grid))

算法复杂度分析

上述算法的时间复杂度为 O(RC),其中 RC 分别为网格的行数和列数。空间复杂度为 O(RC),用于存储被守护的单元格。

总结

本指南详细介绍了如何使用标记法解决 LeetCode 2257 难题。我们通过遍历网格,标记已被守护的单元格,然后计算未被守护的单元格数量。该算法的时间复杂度为 O(RC),空间复杂度为 O(RC)