题目

在给定的网格中,每个单元格可以有以下三个值之一:

  • 0 代表空单元格;
  • 1 代表新鲜橘子;
  • 2 代表腐烂的橘子。

每分钟,任何与腐烂的橘子(在 4 个正方向上)相邻的新鲜橘子都会腐烂。

返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1

示例 1:
腐烂的橘子 - 图1
输入:[[2,1,1],[1,1,0],[0,1,1]]
输出:4

示例 2:
输入:[[2,1,1],[0,1,1],[1,0,1]]
输出:-1
解释:左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个正向上。

示例 3:
输入:[[0,2]]
输出:0
解释:因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0 。

提示:

  1. 1 <= grid.length <= 10
  2. 1 <= grid[0].length <= 10
  3. grid[i][j] 仅为 012

    方案一(BFS)

    1. class Solution:
    2. def orangesRotting(self, grid: List[List[int]]) -> int:
    3. if not grid or not grid[0]:
    4. return 0
    5. self.m = len(grid)
    6. self.n = len(grid[0])
    7. # BFS
    8. starts = []
    9. n = 0 # 未腐烂橘子的个数
    10. for i in range(self.m):
    11. for j in range(self.n):
    12. if grid[i][j] == 2:
    13. starts.append((i, j))
    14. elif grid[i][j] == 1:
    15. n += 1
    16. if not starts:
    17. if n == 0: # 没有腐烂的橘子,且没有新鲜的橘子
    18. return 0
    19. return -1
    20. deque = collections.deque(starts)
    21. minutes = 0
    22. while deque:
    23. length = len(deque)
    24. minutes += 1
    25. for _ in range(length):
    26. x, y = deque.popleft() # 已腐烂的橘子的坐标
    27. for next_x, next_y in self.surround(x, y):
    28. if grid[next_x][next_y] == 1:
    29. grid[next_x][next_y] = 2
    30. deque.append((next_x, next_y))
    31. for i in range(self.m):
    32. for j in range(self.n):
    33. if grid[i][j] == 1:
    34. return -1
    35. return minutes - 1
    36. def surround(self, x, y):
    37. if x > 0:
    38. yield x - 1, y
    39. if x < self.m - 1:
    40. yield x + 1, y
    41. if y > 0:
    42. yield x, y - 1
    43. if y < self.n - 1:
    44. yield x, y + 1

    原文

    https://leetcode-cn.com/explore/interview/card/2020-top-interview-questions/288/graph/1291/