[Medium] 994. Rotting Oranges

문제

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.

 

예시 

xample 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: -1
Explanation: 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: 0
Explanation: 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.

 

풀이 과정

그리드를 입력 받고 각 값에 0, 1, 또는 2를 할당한다. 

1은 신선한 오렌지, 2는 썩은 오렌지, 0은 빈 공간이다. 

과수원을 지날 때마다 썩은 오렌지에 수평 또는 수직으로 인접한 모든 오렌지도 썩게 된다. 신선한 오렌지가 남지 않을 때까지 경과된 최소 시간(분)을 반환해야 한다.

 

예시 ) 

[0, 0]의 주황색은 손상되어 도착한다. 1분이 지나면 인접한 오렌지도 손상된다. 1분 더 지나면 상할 수 있는 모든 오렌지 가 상하게 된다.

* 참고 사항- 이 특정 예에서는 아직 신선한 오렌지가 남아 있기 때문에 실제로 -1을 반환한다. [2, 2]의 주황색이 없으면 2가 답이 된다.

 

  • 호출 후, cycleOranges는 스톱워치를 증가시키면서 부패 주기를 통해 오렌지의 속도를 높인다. 
  • 이렇게 하면 모든 오렌지가 상할 수 있고 상하기 전에 몇 분이 경과했는지 알 수 있다.
  • 그런 다음 (30행) 스톱워치가 실제로 시간을 기록했는지, 과수원이 '비어 있는지', 즉 존재하는 모든 오렌지가 상했다는 의미인지 확인한다. 
  • 스톱워치 시간에 관계없이 그리드에 여전히 신선한 오렌지가 있으면 -1이 반환된다.

해결 코드

/**
 * @param {number[][]} grid
 * @return {number}
 */
var orangesRotting = function(grid) {
    
  if (emptyOrchard(grid)) {
    return 0;
  } 
  
  var stopwatch = 0;

  var cycleOranges = (grid) => {

    var checked = [];

    for (var i = 0; i < grid.length; i++) {
      for (var j = 0; j < grid[i].length; j++) {
        if (grid[i][j] === 2 && !isDuplicate(checked, [i, j])) {
          var adjacent = adjacencies(grid, i, j);
          if (adjacent) {
            adjacent.forEach(freshOrange => {
              grid[freshOrange[0]][freshOrange[1]] = 2;
              checked.push([freshOrange[0], freshOrange[1]]);
            });
          }  
        }
      }
    }
  stopwatch++;
  return adjacenciesRemain(grid) ? cycleOranges(grid) : null;
  }
  cycleOranges(grid);
  return stopwatch > 0 && emptyOrchard(grid) ? stopwatch : -1; 
};


// 신선한 오렌지 인접 관계에 상한 오렌지가 있는지 없는지 그리드를 점검

var adjacenciesRemain = (grid) => {
  for (var i = 0; i < grid.length; i++) {
    for (var j = 0; j < grid[i].length; j++) {
      if (grid[i][j] === 2 && adjacencies(grid, i, j)) {
        return true;
      }
    }
  }
  return false;
}


// 사용 가능한 모든 인접의 좌표를 확인

var adjacencies = (tree, i, j) => {
  var adjacent = [];
  
  var right = tree[i][j + 1];
  var left = tree[i][j - 1];
  var up = tree[i - 1] === undefined ? undefined : tree[i - 1][j]; 
  var down = tree[i + 1] === undefined ? undefined : tree[i + 1][j];

  right === 1 ? adjacent.push([i, j + 1]) : null;
  up === 1 ? adjacent.push([i - 1, j]) : null;
  left === 1 ? adjacent.push([i, j - 1]) : null;
  down === 1 ? adjacent.push([i + 1, j]) : null;

  return adjacent.length > 0 ? adjacent : false;
  
}


// 인자 어레이의 신뢰성 확인

var isDuplicate = (arr1, arr2) => {
  for (var i = 0; i < arr1.length; i++) {
    if (JSON.stringify(arr1[i]) === JSON.stringify(arr2)) {
      return true;
    }
  }
  return false;
}


// 모든 오렌지가 썩었거나 오렌지가 전혀 없는 상태를 체크

var emptyOrchard = (grid) => {
  
  var rotten = false;
  var fresh = false;
  var absent = false;
  
  for (var i = 0; i < grid.length; i++) {
    for (var j = 0; j < grid[i].length; j++) {
      if (grid[i][j] === 2) {
        rotten = true;
      } else if (grid[i][j] === 1) {
        fresh = true;
      } else if (grid[i][j] === 0) {
        absent = true;
      }
    }
  }
  return (rotten && !fresh) || (absent && !rotten & !fresh);
};

 

 


참고 사이트

https://javascript.plainenglish.io/leetcode-994-rotting-oranges-problem-9596d4f8e923

 

LeetCode #994: Rotting Oranges Problem

Solving the Rotting Oranges Problem with JavaScript.

javascript.plainenglish.io