
解题思路:
- 遍历网格: 逐个检查每个单元格。
- 发现陆地: 当遇到值为 ‘1’ 的单元格时,表示发现新岛屿,计数器加 1。
- 标记访问: 从当前单元格出发,递归访问其上下左右相邻的陆地,并将它们标记为已访问。
- 重复过程: 继续遍历网格直至所有单元格处理完毕。
Java代码:
class Solution {
public int numIslands(char[][] grid) {
int count = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == '1') {
dfs(grid, i, j);
count++;
}
}
}
return count;
}
private void dfs(char[][] grid, int i, int j) {
if (i == -1 || i == grid.length || j == -1 || j == grid[0].length || grid[i][j] != '1') return;
grid[i][j] = '0';
dfs(grid, i + 1, j);
dfs(grid, i - 1, j);
dfs(grid, i, j + 1);
dfs(grid, i, j - 1);
}
}
复杂度分析:
- 时间复杂度: O(mn)。其中 m 是行数,n 是列数。每个单元格最多被访问一次。
- 空间复杂度: O(mn)。最坏情况下(如网格全为陆地),递归深度可达 mn。

解题思路:
- 初始化: 首先遍历整个网格,统计所有新鲜橘子的数量,并将所有初始腐烂橘子的位置加入队列。
- BFS 扩散: 从队列中取出腐烂橘子的位置,检查其四个方向的新鲜橘子,将其腐烂并加入队列。每次处理完一层腐烂橘子(即 BFS 的一层),时间增加一分钟。
- 终止条件: 当队列为空时,检查是否还有新鲜橘子。如果没有,返回总时间;否则返回 -1,表示无法全部腐烂。
Java代码:
class Solution {
public int orangesRotting(int[][] grid) {
Queue<int[]> queue = new LinkedList<>();
int freshOranges = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 2) {
queue.offer(new int[]{i, j});
} else if (grid[i][j] == 1) {
freshOranges++;
}
}
}
if (freshOranges == 0) return 0;
int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int minutes = 0;
while (!queue.isEmpty()) {
int size = queue.size();
boolean changed = false;
for (int i = 0; i < size; i++) {
int[] current = queue.poll();
int x = current[0], y = current[1];
for (int[] dir : directions) {
int newX = x + dir[0];
int newY = y + dir[1];
if (newX >= 0 && newX < grid.length && newY >= 0 && newY < grid[0].length && grid[newX][newY] == 1) {
grid[newX][newY] = 2;
queue.offer(new int[]{newX, newY});
freshOranges--;
changed = true;
}
}
}
if (changed) minutes++;
}
return freshOranges == 0 ? minutes : -1;
}
}
复杂度分析:
- 时间复杂度: O(mn)。其中 m 是行数,n 是列数。每个单元格最多被访问一次。
- 空间复杂度: O(mn)。最坏情况下(如网格全为腐烂橘子),递归深度可达 mn。