题目描述:
在给定的网格中,每个单元格可以有以下三个值之一:
值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,任何与腐烂的橘子(在 4 个正方向上)相邻的新鲜橘子都会腐烂。
返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1。
解法一: BFS
- 建立一个队列,并遍历数组,将腐烂的句子加入到队列中,代表第 0 分钟就全部腐烂了,并统计新鲜橘子的个数。
- 开始出队,如果队列四周有新鲜橘子,将其入队,并设置一个 HashSet 来统计入队的位置,来防止重复添加。
- 直到队列为空,记录此时的队列清空次数和此时入队新鲜橘子个数是否等于初始统计的新鲜橘子个数,可以得到结果。
时间复杂度: O(N); 辅助空间复杂度: O(N)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| class Solution { public int orangesRotting(int[][] grid) { int rows = grid.length; int cols = grid[0].length; Queue<int[]> queue = new LinkedList<>(); int count = 0; int bad = 0; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (grid[i][j] == 1 || grid[i][j] == 2) { count++; if (grid[i][j] == 2) { queue.offer(new int[]{i, j}); bad++; } } } } int res = 0; int totalBad = bad; HashSet<String> set = new HashSet<>(); while (!queue.isEmpty()) { int[] badOrange = queue.poll(); int x = badOrange[0]; int y = badOrange[1]; bad--; if (x > 0 && grid[x - 1][y] == 1 && !set.contains(x - 1 + "_" + y)) { queue.offer(new int[]{x - 1, y}); set.add(x - 1 + "_" + y); } if (x < rows - 1 && grid[x + 1][y] == 1 && !set.contains(x + 1 + "_" + y)) { queue.offer(new int[]{x + 1, y}); set.add(x + 1 + "_" + y); } if (y > 0 && grid[x][y - 1] == 1 && !set.contains(x + "_" + (y - 1))) { queue.offer(new int[]{x, y - 1}); set.add(x + "_" + (y - 1)); } if (y < cols - 1 && grid[x][y + 1] == 1 && !set.contains(x + "_" + (y + 1))) { queue.offer(new int[]{x, y + 1}); set.add(x + "_" + (y + 1)); } if (bad == 0) { bad = queue.size(); if (bad != 0) { res++; totalBad += bad; } } } return totalBad == count ? res : -1; } }
|