Skip to main content

Rotting Oranges

Problem statement

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:

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

Example 2:

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

Example 3:

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

Constraints:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 10
  • grid[i][j] is 0, 1, or 2.

My solution

/**
* @param {number[][]} grid
* @return {number}
*/
var orangesRotting = function(grid) {
const fresh = new Set();
let rottens = new Set();

function makeKey(i, j) {
return `${i}${j}`
}

for (let i = 0; i < grid.length; i++) {
for (let j = 0; j < grid[0].length; j++) {
if (grid[i][j] === 2) {
rottens.add(makeKey(i, j))
} else if (grid[i][j] === 1) {
fresh.add(makeKey(i, j))
}
}
}

let minutes = 0;
const getDirections = (i, j) => [
[i + 1, j],
[i - 1, j],
[i, j + 1],
[i, j - 1],

];

while (fresh.size > 0) {
let infected = new Set();
for (const [rotten] of rottens.entries()) {
const [x, y] = rotten.split("").map(v => parseInt(v, 10))

for (const [newX, newY] of getDirections(x, y)) {
const newKey = makeKey(newX, newY);
if (fresh.has(newKey)) {
fresh.delete(newKey);
infected.add(newKey)
}
}
}

if (infected.size === 0) {
return -1;
}

rottens = infected;
minutes++
}

return minutes;
};