[LeetCode] 994. Rotting Oranges 腐烂的橘子

题目:


思路:

每个腐烂的橘子都能将自己上下左右的新鲜橘子传染,像极了现在的肺炎...

如果格子中只有一个腐烂的橘子,那么这便是一个典型的层次遍历,第一个传染多个,称为第二层,第二层传染第三层

但这里会出现初始时便有多个腐烂橘子的情况,其实道理是一样的,将第一层看成多个而不是一个,同样是层次遍历

这里利用双栈来实现层次遍历:

栈A存储第一批腐烂橘子,将第一批腐烂橘子传染的第二批腐烂橘子的位置全部存储至B,后将A清空,随后将B中第二批传染的第三批的位置存储至A,将B清空,直至AB均空

同时记录新鲜橘子的个数num,若最后num>0,说明不能将所有橘子传染,返回-1

代码:

class Solution {
public:
    // row: 行, col: 列, res: 结果, num: 新鲜橘子数
    int row, col, i, j, res=0, num=0;
    void search(int i, int j, stack<pair<int, int>>& S, vector<vector<int>>& visited, 
      vector<vector<int>>& grid){
        if(i-1>=0 && !visited[i-1][j] && grid[i-1][j]==1) {
            S.push(make_pair(i-1, j));
            visited[i-1][j]=1;
            grid[i-1][j] = 2;
            num--;
            }
            if(j-1>=0 && !visited[i][j-1] && grid[i][j-1]==1) {
            S.push(make_pair(i, j-1));
            visited[i][j-1]=1;
            grid[i][j-1] = 2;
            num--;
            }
            if(i+1<row && !visited[i+1][j] && grid[i+1][j]==1) {
            S.push(make_pair(i+1, j));
            visited[i+1][j]=1;
            grid[i+1][j] = 2;
            num--;
            }
            if(j+1<col && !visited[i][j+1] && grid[i][j+1]==1) {
            S.push(make_pair(i, j+1));
            visited[i][j+1]=1;
            grid[i][j+1] = 2;
            num--;
            }
    }
    int orangesRotting(vector<vector<int>>& grid) {
        row = grid.size();
        col = grid[0].size();
        vector<vector<int>> visited(row, vector<int>(col, 0));
        stack<pair<int, int>>   A, B;
        for(i=0; i<row; i++){
            for(j=0; j<col; j++){
                if(grid[i][j]==2){
                    A.push(make_pair(i, j));
                    visited[i][j]=1;
                }else if(grid[i][j]==1)
                    num++;  // 记录新鲜橘子的个数
            }
        }
        while(!A.empty() || !B.empty()){
            if(A.empty()){
                while(!B.empty()){
                 i=B.top().first;
                 j=B.top().second;
                 search(i, j, A, visited, grid);
                 B.pop();
                }                
            }else{
                while(!A.empty()){
                 i=A.top().first;
                 j=A.top().second;
                 search(i, j, B, visited, grid);
                 A.pop();
                }
            }
            res++;
        }
        if(num) return -1;
        return res==0?res:res-1;
    }
};

注:在最后一层时,没有可以传染的新鲜橘子了,但此时某个栈里仍是非空的(最后一层各个位置),所以res会多加一次,在最后减去就好

同时,如果没有橘子或者本身就是腐烂橘子,res值为0,此时不需要减去1

 
原文地址:https://www.cnblogs.com/ech2o/p/12409316.html