2914. Find The Safest Path In A Grid¶
Difficulty: Medium
LeetCode Problem View on GitHub
2914. Find the Safest Path in a Grid
Medium
You are given a 0-indexed 2D matrix grid of size n x n, where (r, c) represents:
- A cell containing a thief if
grid[r][c] = 1 - An empty cell if
grid[r][c] = 0
You are initially positioned at cell (0, 0). In one move, you can move to any adjacent cell in the grid, including cells containing thieves.
The safeness factor of a path on the grid is defined as the minimum manhattan distance from any cell in the path to any thief in the grid.
Return the maximum safeness factor of all paths leading to cell (n - 1, n - 1).
An adjacent cell of cell (r, c), is one of the cells (r, c + 1), (r, c - 1), (r + 1, c) and (r - 1, c) if it exists.
The Manhattan distance between two cells (a, b) and (x, y) is equal to |a - x| + |b - y|, where |val| denotes the absolute value of val.
Example 1:

Input: grid = [[1,0,0],[0,0,0],[0,0,1]] Output: 0 Explanation: All paths from (0, 0) to (n - 1, n - 1) go through the thieves in cells (0, 0) and (n - 1, n - 1).
Example 2:

Input: grid = [[0,0,1],[0,0,0],[0,0,0]] Output: 2 Explanation: The path depicted in the picture above has a safeness factor of 2 since: - The closest cell of the path to the thief at cell (0, 2) is cell (0, 0). The distance between them is | 0 - 0 | + | 0 - 2 | = 2. It can be shown that there are no other paths with a higher safeness factor.
Example 3:

Input: grid = [[0,0,0,1],[0,0,0,0],[0,0,0,0],[1,0,0,0]] Output: 2 Explanation: The path depicted in the picture above has a safeness factor of 2 since: - The closest cell of the path to the thief at cell (0, 3) is cell (1, 2). The distance between them is | 0 - 1 | + | 3 - 2 | = 2. - The closest cell of the path to the thief at cell (3, 0) is cell (3, 2). The distance between them is | 3 - 3 | + | 0 - 2 | = 2. It can be shown that there are no other paths with a higher safeness factor.
Constraints:
1 <= grid.length == n <= 400grid[i].length == ngrid[i][j]is either0or1.- There is at least one thief in the
grid.
Solution¶
class Solution {
private int min[][];
private static int dir[][] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
static class State {
int row, col, pRow, pCol;
public State(int row, int col, int pRow, int pCol) {
this.row = row;
this.col = col;
this.pRow = pRow;
this.pCol = pCol;
}
@Override
public String toString() {
return "(" + row + " " + col + " " + pRow + " " + pCol + ")";
}
}
static class Tuple {
int row, col, cost;
public Tuple(int row, int col, int cost) {
this.row = row;
this.col = col;
this.cost = cost;
}
@Override
public String toString() {
return "(" + row + " " + col + " " + cost + ")";
}
}
static class customSort implements Comparator<Tuple> {
@Override
public int compare(Tuple first, Tuple second) {
return Integer.compare(second.cost, first.cost);
}
}
public int maximumSafenessFactor(List<List<Integer>> grid) {
int n = grid.size(), m = grid.get(0).size();
/* How can we find the closest or minimum hamming distance wala thief for each cell ? */
min = new int [n][m];
for (int curr[] : min)
Arrays.fill(curr, (int)(1e9));
Queue<State> q = new LinkedList<>();
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid.get(i).get(j) == 1) {
q.offer(new State(i, j, i, j));
min[i][j] = 0;
}
}
}
while (q.size() > 0) {
int currRow = q.peek().row, currCol = q.peek().col, pRow = q.peek().pRow, pCol = q.peek().pCol;
q.poll();
for (int dire[] : dir) {
int newRow = currRow + dire[0], newCol = currCol + dire[1];
if (newRow >= 0 && newRow < n && newCol >= 0 && newCol < m) {
int newDist = Math.abs(pRow - newRow) + Math.abs(pCol - newCol);
if (min[newRow][newCol] > newDist) {
min[newRow][newCol] = newDist;
q.offer(new State(newRow, newCol, pRow, pCol));
}
}
}
}
int low = 0, high = (int)(1e9), ans = -1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (ok(mid, grid)) {
ans = mid;
low = mid + 1;
}
else
high = mid - 1;
}
return ans;
}
private boolean ok(int target, List<List<Integer>> arr) {
int n = arr.size(), m = arr.get(0).size();
if (min[0][0] < target) return false;
PriorityQueue<Tuple> pq = new PriorityQueue<>(new customSort());
int dist[][] = new int[n][m];
for (int curr[] : dist)
Arrays.fill(curr, (int)(-1e9));
dist[0][0] = min[0][0];
pq.offer(new Tuple(0, 0, min[0][0]));
while (pq.size() > 0) {
int currRow = pq.peek().row, currCol = pq.peek().col, currCost = pq.peek().cost;
pq.poll();
if (currRow == n - 1 && currCol == m - 1)
return true;
for (int dire[] : dir) {
int newRow = currRow + dire[0], newCol = currCol + dire[1];
if (newRow >= 0 && newCol >= 0 && newRow < n && newCol < m) {
if (dist[newRow][newCol] < Math.min(min[newRow][newCol], currCost)) {
if (Math.min(min[newRow][newCol], currCost) >= target) {
dist[newRow][newCol] = Math.min(min[newRow][newCol], currCost);
pq.offer(new Tuple(newRow, newCol, dist[newRow][newCol]));
}
}
}
}
}
return false;
}
}
Complexity Analysis¶
- Time Complexity:
O(?) - Space Complexity:
O(?)
Approach¶
Detailed explanation of the approach will be added here