Problem
Analysis Process
BFS
1.To start with, we take all the rotten oranges, and we queue them up as nodes at level 0
2.Then BFS is carried out. The adjacent nodes of each node may be nodes in four directions, top, bottom, left and right. Pay attention to the special cases where nodes are located at the grid boundary
3.Since there may be oranges that cannot be contaminated, we need to record the number of fresh oranges in BFS. Every time we traverse an orange (contaminated an orange), we will reduce the number of fresh oranges by one. If the number is still not reduced to zero after BFS, it means that there are oranges that cannot be contaminated
golang
func orangesRotting(grid [][]int) int {
//Empty square, return 0
if len(grid) == 0 {
return 0
}
w, h := len(grid), len(grid[0])
queue := [][]int{} //rotten orange
healthyCount := 0 //the sum of fresh orange
for i := 0; i < w; i++ {
for j := 0; j < h; j++ {
if grid[i][j] == 2 {
queue = append(queue, []int{i, j}) //push
} else if grid[i][j] == 1 {
healthyCount++ //the sum of fresh orange increases
}
}
}
var t = 0 //Number of cycles or layers or minutes
for healthyCount > 0 && len(queue) > 0 { //no fresh orange or null ,break
t++ //The number of cycles plus 1
ql := len(queue) //The number of queues to consume in this loop, since the queue will continue to be blocked, so let's figure out the length first
for i := 0; i < ql; i++ { //将The local queue is consumed
one := queue[0] //And every time you pull out the first one, it's equivalent to the queue head
x, y := one[0], one[1] //The coordinates of the rotten oranges
queue = queue[1:] //pop
if y-1 >= 0 && grid[x][y-1] == 1 { //The upper adjacent determines whether the boundary and the upper adjacent is a healthy orange
grid[x][y-1] = 2 //Infection
healthyCount-- //fresh orange -1
queue = append(queue, []int{x, y - 1}) //Queue and cache the infected oranges
}
if y+1 < h && grid[x][y+1] == 1 { //The neighboring points
grid[x][y+1] = 2
healthyCount--
queue = append(queue, []int{x, y + 1})
}
if x-1 >= 0 && grid[x-1][y] == 1 { //Left adjacent points
grid[x-1][y] = 2
healthyCount--
queue = append(queue, []int{x - 1, y})
}
if x+1 < w && grid[x+1][y] == 1 { //Right adjacent points
grid[x+1][y] = 2
healthyCount--
queue = append(queue, []int{x + 1, y})
}
}
}
if healthyCount > 0 {
//if still fresh orange
// return -1
// or return level
return -1
} else {
return t
}
}
java
class Solution {
public int orangesRotting(int[][] grid) {
// Boundary width
int M = grid.length;
int N = grid[0].length;
Queue<int[]> queue = new LinkedList<>();
// count represents the number of fresh oranges
int count = 0;
// Traverse a two-dimensional array to find all the fresh and rotten oranges
for (int r = 0; r < M; r++) {
for (int c = 0; c < N; c++) {
// Fresh orange count
if (grid[r][c] == 1) {
count++;
// Rotten oranges are put in the queue
} else if (grid[r][c] == 2) {
// Cache rotten orange coordinates
queue.add(new int[]{r, c});
}
}
}
// round represents the number of rotten rounds, or minutes
int round = 0;
// If there are fresh oranges and the queue is not empty
// Until the top, bottom, left and right touch the boundary or the infected orange has been traversed
while (count > 0 && !queue.isEmpty()) {
// BFS level + 1
round++;
// Get the number of rotten oranges at the current level, because each level updates the queue
int n = queue.size();
// Traversal the queue at the current level
for (int i = 0; i < n; i++) {
// Kick out of line (take out a rotten orange)
int[] orange = queue.poll();
// Restore the orange coordinates
int r = orange[0];
int c = orange[1];
// The upper adjacent determines whether the boundary and the upper adjacent is a healthy orange
if (r-1 >= 0 && grid[r-1][c] == 1) {
// Infection
grid[r-1][c] = 2;
// fresh orange -1
count--;
// Queue and cache the infected oranges
queue.add(new int[]{r-1, c});
}
// The neighboring points
if (r+1 < M && grid[r+1][c] == 1) {
grid[r+1][c] = 2;
count--;
queue.add(new int[]{r+1, c});
}
// Left adjacent points
if (c-1 >= 0 && grid[r][c-1] == 1) {
grid[r][c-1] = 2;
count--;
queue.add(new int[]{r, c-1});
}
// Right adjacent points
if (c+1 < N && grid[r][c+1] == 1) {
grid[r][c+1] = 2;
count--;
queue.add(new int[]{r, c+1});
}
}
}
// if still fresh orange
// return -1
// or return level
if (count > 0) {
return -1;
} else {
return round;
}
}
}