Hard
Minimum Time Takes to Reach Destination Without Drowning — C++
Full explanation · Time O(m * n) · Space O(m * n)
// Time: O(m * n)
// Space: O(m * n)
// simulation, bfs
class Solution {
public:
int minimumSeconds(vector<vector<string>>& land) {
static const vector<pair<int, int>> DIRECTIONS {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
vector<vector<int>> lookup(size(land), vector<int>(size(land[0])));
vector<tuple<int, int, int>> q;
int i0 = -1, j0 = -1;
for (int i = 0; i < size(land); ++i) {
for (int j = 0; j < size(land[0]); ++j) {
if (land[i][j] == "*") {
q.emplace_back(i, j, -1);
lookup[i][j] = -1;
} else if (land[i][j] == "S") {
i0 = i, j0 = j;
}
}
}
q.emplace_back(i0, j0, 1);
lookup[i0][j0] = 1;
while (!empty(q)) {
vector<tuple<int, int, int>> new_q;
for (const auto& [i, j, d] : q) {
if (land[i][j] == "D") {
return d - 1;
}
for (const auto& [di, dj] : DIRECTIONS) {
const int ni = i + di, nj = j + dj;
if (!(0 <= ni && ni < size(land) && 0 <= nj && nj < size(land[0]) && land[ni][nj] != "X" && lookup[ni][nj] != -1)) {
continue;
}
if (d != -1 && lookup[ni][nj] == 0) {
lookup[ni][nj] = 1;
new_q.emplace_back(ni, nj, d + 1);
} else if (d == -1 && land[ni][nj] != "D") {
lookup[ni][nj] = -1;
new_q.emplace_back(ni, nj, -1);
}
}
}
q = move(new_q);
}
return -1;
}
};
// Time: O(m * n)
// Space: O(m * n)
// simulation, bfs
class Solution2 {
public:
int minimumSeconds(vector<vector<string>>& land) {
static const vector<pair<int, int>> DIRECTIONS {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
vector<vector<int>> lookup1(size(land), vector<int>(size(land[0]), -1));
vector<vector<int>> lookup2(size(land), vector<int>(size(land[0]), -1));
vector<pair<int, int>> q1;
vector<pair<int, int>> q2;
for (int i = 0; i < size(land); ++i) {
for (int j = 0; j < size(land[0]); ++j) {
if (land[i][j] == "*") {
q1.emplace_back(i, j);
lookup2[i][j] = 0;
} else if (land[i][j] == "S") {
q2.emplace_back(i, j);
lookup2[i][j] = 0;
}
}
}
while (!empty(q1) || !empty(q2)) {
vector<pair<int, int>> new_q1;
vector<pair<int, int>> new_q2;
for (const auto& [i, j] : q1) {
for (const auto& [di, dj] : DIRECTIONS) {
const int ni = i + di, nj = j + dj;
if (!(0 <= ni && ni < size(land) && 0 <= nj && nj < size(land[0]) && land[ni][nj] != "X" && land[ni][nj] != "D" && lookup1[ni][nj] == -1)) {
continue;
}
lookup1[ni][nj] = 0;
new_q1.emplace_back(ni, nj);
}
}
for (const auto& [i, j] : q2) {
if (land[i][j] == "D") {
return lookup2[i][j];
}
for (const auto& [di, dj] : DIRECTIONS) {
const int ni = i + di, nj = j + dj;
if (!(0 <= ni && ni < size(land) && 0 <= nj && nj < size(land[0]) && land[ni][nj] != "X" && lookup2[ni][nj] == -1 && lookup1[ni][nj] == -1)) {
continue;
}
lookup2[ni][nj] = lookup2[i][j] + 1;
new_q2.emplace_back(ni, nj);
}
}
q1 = move(new_q1);
q2 = move(new_q2);
}
return -1;
}
};