题目:给定一个n m的网格,其中每个单元格中可能有三种值。分别是0,1,2。
0表示这个格子为空,1表示这个格子有一个完好的苹果,2表示这个格子有一个腐烂的苹果。
腐烂的苹果每分钟会向上下左右四个方向的苹果传播一次病菌,并导致相邻的苹果腐烂。请问经过多少分钟,网格中不存在完好的苹果。如果有苹果永远不会腐烂则返回-1。
数据范围:1 n , m
100 , 网络中的值满足0
val
2
测试用例:
用例1
输入:[[2,1,1],[1,1,0],[0,1,1]]
输出:4
用例2
输入:[[2,1,1],[1,0,1],[1,1,1]]
输出:4
题目评价:
本人是最讨厌这种类型的题目,感觉特别麻烦(本人太菜了)。但这种题目的主流解法有两种:广度优先搜索(BFS)和 队列实现。
解题思路:
方法一(BFS):
首先分别将腐烂的橘子和新鲜的橘子保存在两个集合中;
模拟广度优先搜索的过程,方法是判断在每个腐烂橘子的四个方向上是否有新鲜橘子,如果有就腐烂它。每腐烂一次时间加 11,并剔除新鲜集合里腐烂的橘子;
当橘子全部腐烂时结束循环。
func orangesRotting(grid [][]int) int {
if !hasFresh(grid) {
return 0
}
time := getTimes(grid)
if hasFresh(grid) {
return -1
}
return time
}
func hasFresh(grid [][]int) bool {
for i := range grid {
for _, val := range grid[i] {
if 1 == val {
return true
}
}
}
return false
}
func getTimes(grid [][]int) int {
q := getQueue(grid)
time := 0
for len(q) > 0 {
next := make([][]int, 0)
for i := range q {
row := q[i][0]
col := q[i][1]
next = setRot(grid, next, row-1, col)
next = setRot(grid, next, row, col+1)
next = setRot(grid, next, row+1, col)
next = setRot(grid, next, row, col-1)
}
if len(next) != 0 {
time++
}
q = next
}
return time
}
func getQueue(grid [][]int) [][]int {
q := make([][]int, 0)
for i := range grid {
for j, val := range grid[i] {
if 2 == val {
q = append(q, []int{i, j})
}
}
}
return q
}
func setRot(grid, q [][]int, row, col int) [][]int {
if row < 0 || col < 0 || row >= len(grid) || col >= len(grid[0]) || grid[row][col] != 1 {
return q
}
grid[row][col] = 2
q = append(q, []int{row, col})
return q
}
方法二( 队列实现):
// 位置结构体
type Pos struct {r,c int}
// 队列
type Queue []Pos
// 入队
func (this *Queue)Push(x Pos) {
(*this) = append(*this,x)
}
// 出队
func (this *Queue)Pop() Pos {
res := (*this)[0]
(*this) = (*this)[1:len(*this)]
return res
}
// 判断队空
func (this Queue)IsEmpty() bool {
if len(this) == 0 {return true}
return false
}
func orangesRotting(grid [][]int) int {
res := -1
n,m := len(grid),len(grid[0])
dir := [][2]int{{1,0},{-1,0},{0,1},{0,-1}} // 方向矢量
num1,num2 := 0,0 // 记录每一层腐烂橘子的数目
flag := false // 记录初始状态下是否含有新鲜橘子
var ql Queue
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
if grid[i][j] == 2 { // 把第一层腐烂橘子入队并计数
ql.Push(Pos{i,j})
num1++
}
if grid[i][j] == 1 {flag = true}
}
}
if num1 == 0 { // 若没有腐烂的橘子结果取决于有无新鲜的橘子
if flag {return -1}
return 0
}
for !ql.IsEmpty() {
now := ql.Pop()
for i := 0; i < 4; i++ {
r,c := now.r+dir[i][0],now.c+dir[i][1]
if r >= 0 && r < n && c >= 0 && c < m && grid[r][c] == 1 {
grid[r][c] = 2
ql.Push(Pos{r,c})
num2++
}
}
num1--
if num1 == 0 { // 遍历完一层就记一次数
res++
num1 = num2
num2 = 0
}
}
// 判断是否还有新鲜的橘子
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
if grid[i][j] == 1 {return -1}
}
}
return res
}
如果还是看不懂,可以看这个力扣网站上面的这道题目,相信对你有所帮助力扣
https://leetcode.cn/problems/rotting-oranges/
本文介绍了一种模拟腐烂苹果如何在网格中扩散的算法问题。通过两种方法——广度优先搜索(BFS)和队列实现,来解决网格中所有好苹果最终腐烂所需的时间。若存在无法腐烂的好苹果,则返回-1。
&spm=1001.2101.3001.5002&articleId=126909915&d=1&t=3&u=bee69924e22040498acff7e1d37c2f90)
374

被折叠的 条评论
为什么被折叠?



