タイトル
所与のグリッドでは、各セルは、3つの値のいずれかを有することができます。
値0は、空のセルを表し、
新鮮なオレンジの値1、
値が腐敗オレンジを表します。
毎分、あらゆる腐敗オレンジ(4つの方向の正)と新鮮なオレンジの腐敗に隣接しています。
オレンジのフレッシュが通過しなければならないまで、セルは分の最小数まで戻りません。可能でない場合は、-1を返します。
例1
输入:[[2,1,1],[1,1,0],[0,1,1]]
输出:4
例2
输入:[[2,1,1],[0,1,1],[1,0,1]]
输出:-1
解释:左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个正向上。
例3
输入:[[0,2]]
输出:0
解释:因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0 。
思考
- たびに、すべての腐ったみかんは良いオレンジは、約1分間と呼ばれるこの時間は腐ったみかんになると考えています。
- キューは、最初のキューサイズ腐ったみかんの代表者の数と、すべての腐ったみかんの座標で保存します。それは良いとの良好なオレンジ色の数を表します。
- オレンジ色の良い感染周りの腐ったオレンジキュー抽出、マイナス1からサイズ。オレンジは良い、良いマイナス1に感染していました。良いオレンジ色に感染し、キューに。サイズは、腐ったオレンジの最初のバッチは上感染していることを示し、ゼロになったとき。この時点でキューがオレンジになっては良い腐ったみかんがないことを示す、空の場合、サイクルが終了することができます。キューが空でない場合、この時点で、後ケースの長さに設定されたキュー・サイズは、サイクルが継続します。
- それは0、-1でない場合、サイクルの終わりに、それは、良い良いオレンジ番号0か否かが判断されます。
コード
class Solution {
private:
int rows, cols;
public:
int orangesRotting(vector<vector<int>>& grid) {
if ( grid.size() == 0 ) return 0;
rows = grid.size();
cols = grid[0].size();
vector<vector<int>> pattern = { {0, 1}, {0, -1}, {1, 0}, {-1, 0} };
int ans = 0;
queue<vector<int>> q;
int goodOranges = 0; // 好橘子的数量
// 找到所有腐烂的橘子
for ( int row = 0; row < rows; ++row ) {
for ( int col = 0; col < cols; ++col ) {
if ( grid[row][col] == 2 )
q.push( {row, col} );
else if ( grid[row][col] == 1 )
++goodOranges;
}
}
int size = q.size(); // 0 时刻怀橘子的数量
while ( !q.empty() ) {
while ( size-- ) {
vector<int> pos = q.front();
q.pop();
for ( auto& vec : pattern ) {
int nRow = vec[0] + pos[0];
int nCol = vec[1] + pos[1];
if ( isValid( nRow, nCol ) && grid[nRow][nCol] == 1 ) {
grid[nRow][nCol] = 2;
q.push( {nRow, nCol } );
--goodOranges; // 新增一个坏橘子,减少一个好橘子。
}
}
}
if ( q.empty() ) break; // 如果q.empty()为空,说明没新增腐烂的橘子
++ans;
size = q.size(); // 下一时刻坏橘子的数量
}
if ( goodOranges != 0 ) ans = -1; // 还有好橘子
return ans;
}
bool isValid( int row, int col ) {
return row >=0 && row < rows && col >=0 && col < cols;
}
};