置頂 0%

994.Rotting Oranges

This question on LeetCode has been bothering me for a couple of days and afterwards I understood that the typical solution is to use BFS for the cases specified in the description of the question. Therefore, I take a note to let me memorize the solution to this problem next time.

Question

You are given an m x n grid where each cell can have one of three values:

  • 0 representing an empty cell,
  • 1 representing a fresh orange, or
  • 2 representing a rotten orange.
    Every minute, any fresh orange that is 4-directionally adjacent to a rotten orange becomes rotten.

Return the minimum number of minutes that must elapse until no cell has a fresh orange. If this is impossible, return -1.
Example 1:

1
2
Input: grid = [[2,1,1],[1,1,0],[0,1,1]]
Output: 4

Example 2:

1
2
3
Input: grid = [[2,1,1],[0,1,1],[1,0,1]]
Output: -1
Explanation: The orange in the bottom left corner (row 2, column 0) is never rotten, because rotting only happens 4-directionally.

Example 3:

1
2
3
Input: grid = [[0,2]]
Output: 0
Explanation: Since there are already no fresh oranges at minute 0, the answer is just 0.

Solution (Good)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// Time Complexity: O(M*N)
// Space Complexity: O(M*N)
class Solution {
public int orangesRotting(int[][] grid) {
// Initial Fresh Oranges
int freshCount = 0;
int rows = grid.length, cols = grid[0].length;
Queue<int[]> queue = new LinkedList<>();

// This step is to put all the rotten oranges in queue and Count the number of Fresh Oranges
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (grid[i][j] == 1) {
freshCount++;
} else if (grid[i][j] == 2) {
queue.offer(new int[]{i, j});
}
}
}

int step = 0;
// For Movement Usage
int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
// BFS starting from initially rotten oranges
while (!queue.isEmpty() && freshCount > 0) {
int size = queue.size();

for (int i = 0; i < size; i++) {
int[] curr = queue.poll();
for (int[] dir : directions) {
int nextX = curr[0] + dir[0];
int nextY = curr[1] + dir[1];
if (nextX < 0 || nextX >= rows || nextY < 0 || nextY >= cols || grid[nextX][nextY] != 1) {
continue;
}
queue.offer(new int[]{nextX, nextY});
grid[nextX][nextY] = 2;
freshCount--;
}
}

step++;
}

return freshCount == 0 ? step : -1;
}
}

Solution (Normal)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
class Solution {
public int orangesRotting(int[][] grid) {
int freshCount = 0;
int rows = grid.length, cols = grid[0].length;
Queue<int[]> queue = new LinkedList<>();
List<String> freshList = new ArrayList<>();
List<String> usedList = new ArrayList<>();

//record fresh orange
for(int i=0; i<rows; i++) {
for(int j=0; j<cols;j++) {
int status = grid[i][j];
if(status == 1) {
freshList.add(String.format("%d,%d", j, i));
} else if(status == 2) {
queue.add(new int[]{i, j, 1});
}
}
}

int maxSecond = 0;
while(!queue.isEmpty() && !freshList.isEmpty()) {
int[] currRottingOrange = queue.poll();
int x = currRottingOrange[0];
int y = currRottingOrange[1];
int second = currRottingOrange[2];
maxSecond = Math.max(maxSecond, second);
if(x+1<cols) {
String loc = String.format("%d,%d", x+1, y);
if(freshList.contains(loc)) {
freshList.remove(loc);
if(!usedList.contains(loc)) {
usedList.add(loc);
queue.add(new int[]{x+1, y, second+1});
}
}
}
if(x-1>=0) {
String loc = String.format("%d,%d", x-1, y);
if(freshList.contains(loc)) {
freshList.remove(loc);
if(!usedList.contains(loc)) {
usedList.add(loc);
queue.add(new int[]{x-1, y, second+1});
}
}
}
if(y+1<rows) {
String loc = String.format("%d,%d", x, y+1);
if(freshList.contains(loc)) {
freshList.remove(loc);
if(!usedList.contains(loc)) {
usedList.add(loc);
queue.add(new int[]{x, y+1, second+1});
}
}
}
if(y-1>=0) {
String loc = String.format("%d,%d", x, y-1);
if(freshList.contains(loc)) {
freshList.remove(loc);
if(!usedList.contains(loc)) {
usedList.add(loc);
queue.add(new int[]{x, y-1, second+1});
}
}
}
second++;
}

return freshList.isEmpty() ? maxSecond : -1;
}
}

Reference: