返回

探索岛屿之魅:解密 695. 岛屿的最大面积

后端


寻找岛屿最大面积的征途

在计算机科学领域,算法问题是程序员经常遇到的挑战。算法的本质是通过有限步骤解决复杂问题。LeetCode 695. 岛屿的最大面积就是一个经典的算法问题,它要求我们找到一个由相邻 1 组成的二进制网格(或矩阵)中最大面积的岛屿。

一个岛屿是一个由相邻 1 组成的区域,其中相邻指的是水平或垂直方向上相邻。岛屿的最大面积就是这个岛屿中 1 的数量。

解决这个问题的方法有很多种,包括深度优先搜索、广度优先搜索和并查集。每种方法都有其优缺点,在不同的情况下可能有不同的效率。

深度优先搜索:循序渐进,步步为营

深度优先搜索(DFS)是一种常见的算法,它通过递归的方式深度探索问题空间。DFS 的思想是,从一个结点开始,依次探索其所有相邻结点,然后继续探索这些相邻结点的相邻结点,以此类推,直到探索完所有可达的结点。

在 LeetCode 695 问题中,我们可以使用 DFS 从一个 1 开始搜索,并标记所有相邻的 1。然后,我们可以继续搜索这些 1 的相邻 1,直到搜索完所有可达的 1。这样,我们就找到了一个岛屿,并且可以计算出这个岛屿的面积。

广度优先搜索:层层深入,环环相扣

广度优先搜索(BFS)是一种与 DFS 相似的算法,但它不是深度探索问题空间,而是广度探索问题空间。BFS 的思想是,从一个结点开始,依次探索其所有相邻结点,然后继续探索这些相邻结点的相邻结点,以此类推,直到探索完所有可达的结点。

在 LeetCode 695 问题中,我们可以使用 BFS 从一个 1 开始搜索,并将所有相邻的 1 加入一个队列中。然后,我们可以从队列中取出一个 1,并将其所有相邻的 1 加入队列中。这样,我们就找到了一个岛屿,并且可以计算出这个岛屿的面积。

并查集:高效合并,巧妙求解

并查集是一种高效的数据结构,它可以用于维护一组元素的集合。并查集支持两种主要操作:查找和合并。查找操作可以找到一个元素所在的集合,合并操作可以将两个集合合并为一个集合。

在 LeetCode 695 问题中,我们可以使用并查集来维护所有 1 的集合。当我们找到一个新的 1 时,我们可以使用查找操作找到这个 1 所在的集合,然后使用合并操作将这个 1 的集合与相邻 1 的集合合并为一个集合。这样,我们就可以找到所有岛屿,并且可以计算出每个岛屿的面积。

示例代码:清晰简洁,一目了然

以下是用 Python 实现的 DFS、BFS 和并查集算法的示例代码:

# DFS
def maxAreaOfIslandDFS(grid):
    if not grid:
        return 0

    rows, cols = len(grid), len(grid[0])
    max_area = 0

    def dfs(row, col):
        if row < 0 or row >= rows or col < 0 or col >= cols or grid[row][col] == 0:
            return 0

        grid[row][col] = 0  # Mark the cell as visited
        area = 1
        area += dfs(row + 1, col)
        area += dfs(row - 1, col)
        area += dfs(row, col + 1)
        area += dfs(row, col - 1)
        return area

    for row in range(rows):
        for col in range(cols):
            if grid[row][col] == 1:
                max_area = max(max_area, dfs(row, col))

    return max_area


# BFS
def maxAreaOfIslandBFS(grid):
    if not grid:
        return 0

    rows, cols = len(grid), len(grid[0])
    max_area = 0

    def bfs(row, col):
        queue = [(row, col)]
        area = 0

        while queue:
            row, col = queue.pop(0)
            if row < 0 or row >= rows or col < 0 or col >= cols or grid[row][col] == 0:
                continue

            grid[row][col] = 0  # Mark the cell as visited
            area += 1
            queue.append((row + 1, col))
            queue.append((row - 1, col))
            queue.append((row, col + 1))
            queue.append((row, col - 1))

        return area

    for row in range(rows):
        for col in range(cols):
            if grid[row][col] == 1:
                max_area = max(max_area, bfs(row, col))

    return max_area


# Union Find
class UnionFind:
    def __init__(self, n):
        self.parent = [i for i in range(n)]
        self.size = [1] * n

    def find(self, p):
        if self.parent[p] != p:
            self.parent[p] = self.find(self.parent[p])
        return self.parent[p]

    def union(self, p, q):
        root_p = self.find(p)
        root_q = self.find(q)
        if root_p == root_q:
            return

        if self.size[root_p] < self.size[root_q]:
            self.parent[root_p] = root_q
            self.size[root_q] += self.size[root_p]
        else:
            self.parent[root_q] = root_p
            self.size[root_p] += self.size[root_q]

def maxAreaOfIslandUF(grid):
    if not grid:
        return 0

    rows, cols = len(grid), len(grid[0])
    max_area = 0

    uf = UnionFind(rows * cols)
    component_size = [0] * (rows * cols)

    def get_index(row, col):
        return row * cols + col

    for row in range(rows):
        for col in range(cols):
            if grid[row][col] == 0:
                continue

            index = get_index(row, col)
            component_size[index] = 1

            # Check the left cell
            if col > 0 and grid[row][col - 1] == 1:
                left_index = get_index(row, col - 1)
                uf.union(index, left_index)
                component_size[index] += component_size[left_index]

            # Check the top cell
            if row > 0 and grid[row - 1][col] == 1:
                top_index = get_index(row - 1, col)
                uf.union(index, top_index)
                component_size[index] += component_size[top_index]

            max_area = max(max_area, component_size[index])

    return max_area

结语: алгоритмы 的艺术

LeetCode 695. 岛屿的最大面积问题是一个经典的算法问题,它要求我们找到一个由相邻 1 组成的二进制网格(或矩阵)中最大面积的岛屿。我们介绍了三种解决该问题的不同方法:深度优先搜索、广度优先搜索和并查集。每种方法都有其优缺点,在不同的情况下可能有不同的效率。我们还提供了示例代码和详细的解释,帮助读者更好地理解该问题的解决过程。

算法问题是计算机科学领域的重要组成部分,它不仅是程序员必备的基础技能,也是解决现实世界问题的有力工具。希望这篇文章能激发您对算法问题的兴趣,并鼓励您不断学习和探索算法的奥秘。