解法一: BFS
标准的图BFS遍历思路
func orangesRotting(grid [][]int) int {
// 把所有的腐烂橘子加入队列
queue := make([][]int, 0) // 存储元素是每个格子的二维坐标
for i:=0; i<len(grid); i++{
for j:=0; j<len(grid[i]); j++{
if grid[i][j] == 2{
queue = append(queue, []int{i, j})
}
}
}
mins := 0
// BFS搜索
for len(queue) > 0{
size := len(queue)
for i:=0; i<size; i++{
cell := queue[0] // 取队头元素开始判断
// 判断上下左右的格子是否有新鲜橘子
var x, y int
// 上
x = cell[0]-1
y = cell[1]
if x >= 0 && y >= 0 && x < len(grid) && y <len(grid[0]){
if grid[x][y] == 1{
grid[x][y] = 2
queue = append(queue, []int{x,y})
}
}
// 下
x = cell[0]+1
y = cell[1]
if x >= 0 && y >= 0 && x < len(grid) && y <len(grid[0]){
if grid[x][y] == 1{
grid[x][y] = 2
queue = append(queue, []int{x,y})
}
}
// 左
x = cell[0]
y = cell[1]-1
if x >= 0 && y >= 0 && x < len(grid) && y <len(grid[0]){
if grid[x][y] == 1{
grid[x][y] = 2
queue = append(queue, []int{x,y})
}
}
// 右
x = cell[0]
y = cell[1]+1
if x >= 0 && y >= 0 && x < len(grid) && y <len(grid[0]){
if grid[x][y] == 1{
grid[x][y] = 2
queue = append(queue, []int{x,y})
}
}
queue = queue[1:] // 当前橘子出队
}
mins++
}
// 检查是否还有新鲜橘子
for x := 0; x < len(grid); x++{
for y := 0; y<len(grid[x]); y++{
if grid[x][y] == 1{
return -1
}
}
}
if mins == 0{ // 说明初始既没有腐烂橘子,也没有新鲜橘子
return 0
}
// BFS起点在第一个腐烂橘子处,它是初始就腐烂的,不纳入结果
// BFS总扩散层级-1才是答案
return mins-1
}
可以用方向数组,简化一下二维矩阵上的上下左右遍历
func orangesRotting(grid [][]int) int {
// 把所有的腐烂橘子加入队列
queue := make([][]int, 0) // 存储元素是每个格子的二维坐标
for i:=0; i<len(grid); i++{
for j:=0; j<len(grid[i]); j++{
if grid[i][j] == 2{
queue = append(queue, []int{i, j})
}
}
}
mins := 0
if len(queue) > 0{ // 如果初始就有腐烂橘子,它作为BFS的起点,但是首次遍历到它不计入时间
mins-=1
}
// BFS搜索
dirs := [][]int{{-1,0},{1,0},{0,-1},{0,1}}
for len(queue) > 0{
size := len(queue)
for i:=0; i<size; i++{
cell := queue[0] // 取队头橘子,开始向四周扩散
// 判断上下左右的格子是否有新鲜橘子
for _, dir := range dirs{
x := cell[0] + dir[0]
y := cell[1] + dir[1]
if x >= 0 && y >= 0 && x <len(grid) && y < len(grid[0]){
if grid[x][y] == 1{ // 将相邻的橘子腐烂
grid[x][y] = 2
queue = append(queue, []int{x, y})
}
}
}
queue = queue[1:] // 处理完当前橘子,出队
}
mins++
}
// 检查是否还有新鲜橘子
for x := 0; x < len(grid); x++{
for y := 0; y<len(grid[x]); y++{
if grid[x][y] == 1{
return -1
}
}
}
return mins
}