zoukankan      html  css  js  c++  java
  • [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

     
  • 相关阅读:
    Thread.join
    Thread.yield
    线程的生命周期
    HashMap底层原理
    Web Services
    Struts2框架
    hibernate乐观锁实现原理
    Hibernate框架
    oracle exp 无法导出空表
    linux 远程复制文件或文件夹
  • 原文地址:https://www.cnblogs.com/ech2o/p/12409316.html
Copyright © 2011-2022 走看看