java
复制代码
package top100.图论;
import java.util.LinkedList;
import java.util.Queue;
public class TOP {
//200. 岛屿数量
//网格类问题的 DFS 遍历方法
int[][] ways = new int[][]{{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
public int numIslands(char[][] grid) {
int m = grid.length, n = grid[0].length;
int res = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
res++;
dfs(grid, i, j, m, n);
}
}
}
return res;
}
private void dfs(char[][] grid, int i, int j, int m, int n) {
grid[i][j] = '0';
for (int[] way : ways) {
int x = i + way[0], y = j + way[1];
if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == '1') {
dfs(grid, x, y, m, n);
}
}
}
// 994. 腐烂的橘子
// BFS遍历图
//同时遍历所有的腐烂橘子,类似对k个有序链表排序问题的处理思想,用队列记录当前要处理的结点
public int orangesRotting(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int fresh = 0; //统计新鲜的橘子个数
Queue<int[]> queue = new LinkedList<>(); //记录每轮腐烂的橘子位置
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1) {
fresh++;
} else if (grid[i][j] == 2) {
queue.add(new int[]{i, j});
}
}
}
int[][] ways = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int res = 0;
while (fresh > 0 && !queue.isEmpty()) { //while (fresh > 0)会有死循环,有无法感染到的橘子
res++;
int k = queue.size();
//每轮取出上一轮感染的橘子
for (int i = 0; i < k; i++) {
int[] cur = queue.poll();
for (int[] way : ways) {
int x = cur[0] + way[0];
int y = cur[1] + way[1];
//可以感染的新鲜橘子
if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1) {
fresh--;
grid[x][y] = 2;//将本轮感染的橘子标记,防止重复遍历
queue.add(new int[]{x, y});
}
}
}
}
//有橘子无法感染
if (fresh > 0) {
return -1;
} else {
return res;
}
}
}