class Solution {
private static final int[][] directions = new int[][]{
{ -1, 0 },
{ 0, -1 },
{ 1, 0 },
{ 0, 1 }
};
public int maximumSafenessFactor(List<List<Integer>> grid) {
if (grid.getFirst().getFirst() == 1 || grid.getLast().getLast() == 1) {
return 0;
}
int n = grid.size();
int[][] distGrid = new int[n][n];
for (int i = 0; i < n; i++) {
Arrays.fill(distGrid[i], -1);
}
Queue<int[]> queue = new ArrayDeque<>();
for (int i = 0; i < n; i++) {
List<Integer> row = grid.get(i);
for (int j = 0; j < n; j++) {
if (row.get(j) == 1) {
queue.offer(new int[] { i, j, 0 });
distGrid[i][j] = 0;
}
}
}
while (!queue.isEmpty()) {
int[] locAndThiefDist = queue.poll();
for (int[] direction : directions) {
int x = locAndThiefDist[0] + direction[0];
int y = locAndThiefDist[1] + direction[1];
if (x < 0 || x >= n || y < 0 || y >= n) {
continue;
}
if (distGrid[x][y] == -1) {
int dist = locAndThiefDist[2] + 1;
queue.offer(new int[]{x, y, dist});
distGrid[x][y] = dist;
}
}
}
int[][] safeGrid = new int[n][n];
for (int i = 0; i < n; i++) {
Arrays.fill(safeGrid[i], -1);
}
safeGrid[0][0] = distGrid[0][0];
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> b[2] - a[2]);
pq.offer(new int[] { 0, 0, safeGrid[0][0] });
while (!pq.isEmpty()) {
int[] locAndSafeDist = pq.poll();
for (int[] direction : directions) {
int x = locAndSafeDist[0] + direction[0];
int y = locAndSafeDist[1] + direction[1];
if (x < 0 || x >= n || y < 0 || y >= n) {
continue;
}
int minDist = Math.min(distGrid[x][y], locAndSafeDist[2]);
if (safeGrid[x][y] == -1 || safeGrid[x][y] < minDist) {
pq.offer(new int[]{x, y, minDist});
safeGrid[x][y] = minDist;
}
}
}
return safeGrid[n - 1][n - 1];
}
}
最新回复 (3)
Lvvvv07-01 10:31
1楼
蛮力二分+bfs。很慢,而且好像没法保证第一个bfs的复杂度?但是能过。。
class Solution {
public:
int maximumSafenessFactor(vector<vector<int>>& grid) {
int n = grid.size();
std::vector<std::vector<int>> dis(n,std::vector<int>(n,n));
std::queue<int> q;
std::vector<int> dx = {-1,0,1,0},dy = {0,1,0,-1};
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(grid[i][j] == 1) {
q.push(i * n + j);
dis[i][j] = 0;
}
}
}
while(!q.empty()) {
auto id = q.front();
q.pop();
int x = id / n, y = id % n;
for(int i = 0; i < 4; i++) {
int nx = x + dx[i],ny = y + dy[i];
if(nx >= 0 && nx < n && ny >= 0 && ny < n) {
if(dis[nx][ny] > dis[x][y] + 1) {
dis[nx][ny] = dis[x][y] + 1;
q.push(nx * n + ny);
}
}
}
}
int l = -1,r = n;
auto jud = [&](int len) -> bool {
queue<int> q;
std::vector<std::vector<bool>> st(n,std::vector<bool>(n,false));
if(dis[0][0] >= len) {
q.push(0);
st[0][0] = true;
}
while(!q.empty()) {
auto id = q.front();
q.pop();
int x = id / n, y = id % n;
for(int i = 0; i < 4; i++) {
int nx = x + dx[i], ny = y + dy[i];
if(nx >= 0 && nx < n && ny >= 0 && ny < n) {
if(dis[nx][ny] >= len && !st[nx][ny]) {
if(nx == n - 1 && ny == n - 1) {
return true;
}
st[nx][ny] = true;
q.push(nx * n + ny);
}
}
}
}
return false;
};
while(r - l > 1) {
int mid = (l + r) >> 1;
if(jud(mid)) l = mid;
else r = mid;
}
return max(0,l);
}
};
class Solution {
public:
int maximumSafenessFactor(vector<vector<int>>& grid) {
int n = grid.size();
vector<int> dis(n * n, 1E9);
auto encode = [&](int x, int y) -> int {
return x * n + y;
};
using PII = pair<int, int>;
auto decode = [&](int x) -> PII {
return {x / n, x % n};
};
queue<int> q;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1) {
int id = encode(i, j);
dis[id] = 0;
q.push(id);
}
}
}
vector<array<int, 2>> d = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
while (!q.empty()) {
int id = q.front();
q.pop();
auto [x, y] = decode(id);
for (int i = 0; i < 4; i++) {
int nx = x + d[i][0], ny = y + d[i][1];
if (nx >= n || ny >= n || nx < 0 || ny < 0) continue;
int nid = encode(nx, ny);
if (dis[nid] > dis[id] + 1) {
dis[nid] = dis[id] + 1;
q.push(nid);
}
}
}
auto check = [&](int mid) -> bool {
if (dis[encode(0, 0)] < mid || dis[encode(n - 1, n - 1)] < mid) return false;
queue<int> q;
vector<int> vis2(n * n);
q.emplace(encode(0, 0));
vis2[encode(0, 0)] = 1;
while (!q.empty()) {
int id = q.front();
q.pop();
if (id == n * n - 1) return true;
auto [x, y] = decode(id);
for (int i = 0; i < 4; i++) {
int nx = x + d[i][0], ny = y + d[i][1];
if (nx >= n || ny >= n || nx < 0 || ny < 0) continue;
int nid = encode(nx, ny);
if (dis[nid] >= mid && !vis2[nid]) {
vis2[nid] = 1;
q.emplace(nid);
}
}
}
return vis2.back() == 1;
};
int l = 0, r = 2 * n, ans = 0;
while (l <= r) {
int mid = (l + r) / 2;
if (check(mid)) {
l = mid + 1;
ans = mid;
} else {
r = mid - 1;
}
}
return ans;
}
};