标签:广度优先遍历
在给定的m x n网格grid中,每个单元格可以有以下三个值之一:
- 值
0代表空单元格; - 值
1代表新鲜橘子; - 值
2代表腐烂的橘子。
每分钟,腐烂的橘子周围 4 个方向上相邻的新鲜橘子都会腐烂。
返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回-1。
示例 1:
输入:grid = [[2,1,1],[1,1,0],[0,1,1]]
输出:4
示例 2:
输入:grid = [[2,1,1],[0,1,1],[1,0,1]]
输出:-1
解释:左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个方向上。
示例 3:
输入:grid = [[0,2]]
输出:0
解释:因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0 。
思路: 类似 200.岛屿数量,又有点类似 102.二叉树的层序遍历,因为要计数一共递归了几次,因此每次递归需要传新的queue,所有递归公用一个queue,就无法计数了。详细思路见代码注解。
int minute = 0; public int orangesRotting(int[][] grid) { Queue<int[]> queue = new LinkedList<>(); 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}); } } } bfs(grid, queue); // 模拟腐蚀过程 // 仍有橘子没被腐蚀,返回 -1 for(int i = 0; i < grid.length; i++){ for(int j = 0; j < grid[0].length; j++){ if(grid[i][j] == 1){ return -1; } } } return minute; } // 广度优先遍历模拟腐蚀过程 public void bfs(int[][] grid, Queue<int[]> queue){ if(queue.isEmpty()){ return; } Queue<int[]> temp = new LinkedList<>(); while(!queue.isEmpty()){ int[] pos = queue.poll(); int i = pos[0]; int j = pos[1]; if(i - 1 >= 0 && grid[i - 1][j] == 1){ temp.offer(new int[] {i - 1, j}); grid[i - 1][j] = 2; } if(i + 1 < grid.length && grid[i + 1][j] == 1){ temp.offer(new int[] {i + 1, j}); grid[i + 1][j] = 2; } if(j - 1 >= 0 && grid[i][j -1] == 1){ temp.offer(new int[] {i, j - 1}); grid[i][j - 1] = 2; } if(j + 1 < grid[0].length && grid[i][j + 1] == 1){ temp.offer(new int[] {i, j + 1}); grid[i][j + 1] = 2; } } // 成功腐烂一轮才minute++ ,因为像最后一轮被腐蚀的橘子queue,虽然queue != null,也会bfs,但是不会腐蚀其他橘子,因此不计入总腐蚀时间 if(!temp.isEmpty()){ minute++; } bfs(grid, temp); return; }