1. 项目背景与问题定义
最近在准备算法竞赛时遇到一道非常经典的岛屿类题目——"建造最大岛屿"。这类题目在LeetCode、Codeforces等平台上经常出现,也是大厂面试中的高频考题。题目大意是给定一个二维矩阵表示的地图,其中0代表水域,1代表陆地。我们可以将其中一个0改为1(即"填海造陆"),要求找出操作后能形成的最大岛屿面积。
岛屿面积定义为相连的1的数量,其中"相连"指的是上下左右四个方向的相邻。比如下面这个例子:
code复制原始矩阵:
1 0 1
0 0 0
1 0 1
最优解是将中心的0改为1,连接四个角落的1,形成面积为5的岛屿。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 解题思路分析
2.1 基础解法:暴力搜索
最直观的想法是尝试将每个0都改为1,然后计算新形成的岛屿面积,最后取最大值。具体步骤:
- 遍历矩阵中的每个0
- 将其临时改为1
- 使用DFS/BFS计算包含该位置的岛屿面积
- 恢复该位置为0
- 记录所有情况中的最大面积
这种方法的时间复杂度是O(n^4),对于n=50的矩阵就需要约600万次操作,显然不够高效。
2.2 优化思路:连通块预处理
更聪明的做法是预先计算所有现有岛屿的面积,并给每个岛屿编号。然后对于每个0,检查它连接了哪些不同的岛屿,将这些岛屿的面积相加再加1(当前填海的位置)就是潜在的最大面积。
具体步骤:
- 第一次遍历:使用DFS/BFS标记所有现有岛屿,记录每个岛屿的面积和编号
- 第二次遍历:对于每个0,检查其四个邻居的岛屿编号
- 使用集合去重,避免重复计算同一岛屿
- 将不同岛屿的面积相加
- 记录最大的(总面积+1)
这种方法将时间复杂度降到了O(n^2),是典型的空间换时间策略。
3. Java实现详解
3.1 数据结构设计
java复制class Solution {
int[] dr = new int[]{-1, 1, 0, 0}; // 方向数组:上下左右
int[] dc = new int[]{0, 0, -1, 1};
int[][] grid;
int N;
public int largestIsland(int[][] grid) {
t
