[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