题目描述
在给定的 m x n
网格 grid
中,每个单元格可以有以下三个值之一:
-
值
0
代表空单元格; -
值
1
代表新鲜橘子; -
值
2
代表腐烂的橘子。
每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。
返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1
。
示例 1:
输入:grid = [[2,1,1],[1,1,0],[0,1,1]]
输出:4
思路
代码
#include <iostream>
#include <vector>
#include <string>
#include <queue>
using namespace std;
class Solution {
private:
//static constexpr int DIRECTIONS[4][2] = { {0, 1}, {1, 0}, {-1, 0}, {0, -1} };
vector<vector<int>> DIRECTIONS = { {0, 1}, {1, 0}, {0, -1}, {-1, 0} };
public:
int orangesRotting(vector<vector<int>>& grid) {
int level = 0, freshNum = 0, x = grid.size(), y = grid[0].size();
queue<pair<int, int>> q;
vector<vector<int>> checkList(x, vector<int>(y, 0));
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
if (grid[i][j] == 2) {
q.push({ i, j });
checkList[i][j] = 1;
}
else if (grid[i][j] == 1) {
freshNum++;
}
}
}
if (freshNum == 0) {
return 0;
}
while (!q.empty()) {
int qSize = q.size();
level++;
for (int k = 0; k < qSize; k++) {
auto curr = q.front();
q.pop();
int i = curr.first, j = curr.second;
for (auto dir : DIRECTIONS) {
int nextI = i + dir[0], nextJ = j + dir[1];
if (nextI >= 0 && nextI < x && nextJ >= 0 && nextJ < y && checkList[nextI][nextJ] == 0 && grid[nextI][nextJ] == 1) {
q.push({ nextI, nextJ });
checkList[nextI][nextJ] = 1;
freshNum--;
}
}
}
}
return freshNum > 0 ? -1 : level - 1;
}
};
vector<int> split(string params_str) {
vector<int> p;
while (params_str.find(",") != string::npos) {
int found = params_str.find(",");
p.push_back(stoi(params_str.substr(0, found)));
params_str = params_str.substr(found + 1);
}
p.push_back(stoi(params_str));
return p;
}
vector<vector<int>> v;
vector<int> p;
vector<vector<int>> split_2_dimention(string s) {
s += " ";//防止最后一个]后面没有元素所导致的越界
while (s.find("]") != string::npos) {
int found_right = s.find("]");
string s1 = s.substr(1, found_right - 1);
p = split(s1);
v.push_back(p);
s = s.substr(found_right + 2);//取第二个vector,这里可能会越界
p.clear();
}
return v;
}
//grid = [[2,1,1],[1,1,0],[0,1,1]]
int main() {
string input_str;
cin >> input_str;
vector<vector<int>> grid;
grid = split_2_dimention(input_str.substr(1, input_str.size() - 2));
Solution a;
cout << a.orangesRotting(grid) << endl;
}
复杂度分析
时间复杂度:O(nm)。即进行一次广度优先搜索的时间,其中 n,m 分别为 grid 的行数与列数。
空间复杂度:O(nm)。需要额外的 dis 数组记录每个新鲜橘子被腐烂的最短时间,大小为 O(nm),且广度优先搜索中队列里存放的状态最多不会超过 nm 个,最多需要 O(nm) 的空间,所以最后的空间复杂度为 O(nm)。