LeetCode994 腐烂的橘子

58 阅读2分钟

leetcode.cn/problems/ro… image.png

解法一: 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
}

参考

BFS算法框架