LeetCode 2812. Find the Safest Path in a Grid Solution in Java, C++, Python & More | Explanation + Code

CoderIndeed
0
2812. Find the Safest Path in a Grid

Description

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 <= 400
  • grid[i].length == n
  • grid[i][j] is either 0 or 1.
  • There is at least one thief in the grid.

Solutions

Solution 1: BFS + Sorting + Union-Find

We can first find out the positions of all thieves, and then start multi-source BFS from these positions to get the shortest distance from each position to the thieves. Then sort in descending order according to the distance, and add each position to the union-find set one by one. If the start and end points are in the same connected component, the current distance is the answer.

The time complexity is O(n2 × log n), and the space complexity O(n2). Where n is the size of the grid.

PythonJavaC++GoTypeScriptRust
class UnionFind: def __init__(self, n): self.p = list(range(n)) self.size = [1] * n def find(self, x): if self.p[x] != x: self.p[x] = self.find(self.p[x]) return self.p[x] def union(self, a, b): pa, pb = self.find(a), self.find(b) if pa == pb: return False if self.size[pa] > self.size[pb]: self.p[pb] = pa self.size[pa] += self.size[pb] else: self.p[pa] = pb self.size[pb] += self.size[pa] return True class Solution: def maximumSafenessFactor(self, grid: List[List[int]]) -> int: n = len(grid) if grid[0][0] or grid[n - 1][n - 1]: return 0 q = deque() dist = [[inf] * n for _ in range(n)] for i in range(n): for j in range(n): if grid[i][j]: q.append((i, j)) dist[i][j] = 0 dirs = (-1, 0, 1, 0, -1) while q: i, j = q.popleft() for a, b in pairwise(dirs): x, y = i + a, j + b if 0 <= x < n and 0 <= y < n and dist[x][y] == inf: dist[x][y] = dist[i][j] + 1 q.append((x, y)) q = ((dist[i][j], i, j) for i in range(n) for j in range(n)) q = sorted(q, reverse=True) uf = UnionFind(n * n) for d, i, j in q: for a, b in pairwise(dirs): x, y = i + a, j + b if 0 <= x < n and 0 <= y < n and dist[x][y] >= d: uf.union(i * n + j, x * n + y) if uf.find(0) == uf.find(n * n - 1): return int(d) return 0(code-box)

Solution 2

TypeScript
function maximumSafenessFactor(grid: number[][]): number { const n = grid.length; const g = Array.from({ length: n }, () => new Array(n).fill(-1)); const vis = Array.from({ length: n }, () => new Array(n).fill(false)); let q: [number, number][] = []; for (let i = 0; i < n; i++) { for (let j = 0; j < n; j++) { if (grid[i][j] === 1) { q.push([i, j]); } } } let level = 0; while (q.length) { const t: [number, number][] = []; for (const [x, y] of q) { if (x < 0 || y < 0 || x === n || y === n || g[x][y] !== -1) { continue; } g[x][y] = level; t.push([x + 1, y]); t.push([x - 1, y]); t.push([x, y + 1]); t.push([x, y - 1]); } q = t; level++; } const dfs = (i: number, j: number, v: number) => { if (i < 0 || j < 0 || i === n || j === n || vis[i][j] || g[i][j] <= v) { return false; } vis[i][j] = true; return ( (i === n - 1 && j === n - 1) || dfs(i + 1, j, v) || dfs(i, j + 1, v) || dfs(i - 1, j, v) || dfs(i, j - 1, v) ); }; let left = 0; let right = level; while (left < right) { vis.forEach(v => v.fill(false)); const mid = (left + right) >>> 1; if (dfs(0, 0, mid)) { left = mid + 1; } else { right = mid; } } return right; }(code-box)

Post a Comment

0Comments

Post a Comment (0)

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Check Now
Accept !