# LC 2812. Find the Safest Path in a Grid
### [Problem link](https://leetcode.com/problems/find-the-safest-path-in-a-grid/)
###### tags: `leedcode` `python` `medium` `BFS` `Binary Search`
You are given a **0-indexed** 2D matrix <code>grid</code> of size <code>n x n</code>, where <code>(r, c)</code> represents:
- A cell containing a thief if <code>grid[r][c] = 1</code>
- An empty cell if <code>grid[r][c] = 0</code>
You are initially positioned at cell <code>(0, 0)</code>. 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 <code>(n - 1, n - 1)</code>.
An **adjacent** cell of cell <code>(r, c)</code>, is one of the cells <code>(r, c + 1)</code>, <code>(r, c - 1)</code>, <code>(r + 1, c)</code> and <code>(r - 1, c)</code> if it exists.
The **Manhattan distance** between two cells <code>(a, b)</code> and <code>(x, y)</code> is equal to <code>|a - x| + |b - y|</code>, where <code>|val|</code> denotes the absolute value of val.
**Example 1:**
<img alt="" src="https://assets.leetcode.com/uploads/2023/07/02/example1.png" style="width: 362px; height: 242px;" />
```
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:**
<img alt="" src="https://assets.leetcode.com/uploads/2023/07/02/example2.png" style="width: 362px; height: 242px;" />
```
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:**
<img alt="" src="https://assets.leetcode.com/uploads/2023/07/02/example3.png" style="width: 362px; height: 242px;" />
```
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:**
- <code>1 <= grid.length == n <= 400</code>
- <code>grid[i].length == n</code>
- <code>grid[i][j]</code> is either <code>0</code> or <code>1</code>.
- There is at least one thief in the <code>grid</code>.
## Solution 1 - BFS & Binary Search
```python=
class Solution:
def maximumSafenessFactor(self, grid: List[List[int]]) -> int:
n = len(grid)
q = deque()
seen = set()
for i in range(n):
for j in range(n):
if grid[i][j] == 1:
q.append((i, j))
seen.add((i, j))
while q:
x, y = q.popleft()
for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
new_x, new_y = x + dx, y + dy
if 0 <= new_x < n and 0 <= new_y < n and (new_x, new_y) not in seen and grid[new_x][new_y] == 0:
grid[new_x][new_y] = grid[x][y] + 1
q.append((new_x, new_y))
seen.add((new_x, new_y))
# 是否可以找到一條整條都>=num的path
def is_ok(num):
if grid[0][0] < num:
return False
q = deque([(0, 0)])
seen = set([(0, 0)])
while q:
x, y = q.popleft()
if (x, y) == (n - 1, n - 1):
return True
for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
new_x, new_y = x + dx, y + dy
if 0 <= new_x < n and 0 <= new_y < n and (new_x, new_y) not in seen and grid[new_x][new_y] >= num:
q.append((new_x, new_y))
seen.add((new_x, new_y))
return False
left, right = 0, n
while left <= right:
mid = (left + right) // 2
if is_ok(mid):
left = mid + 1
else:
right = mid - 1
return right - 1
```
>### Complexity
>| | Time Complexity | Space Complexity |
>| ----------- | --------------- | ---------------- |
>| Solution 1 | O($n^2logn$) | O($n^2$) |
## Note
sol1:
[官神yt](https://www.youtube.com/watch?v=OjzQ6TmMh6k)
(1)先以每個thief為起點做BFS, 找出每個點到任一thief的最短距離(1-indexed), 以Example 3為例:
```python=
grid:
[0, 0, 0, 1] [4, 3, 2, 1]
[0, 0, 0, 0] => [3, 4, 3, 2]
[0, 0, 0, 0] [2, 3, 4, 3]
[1, 0, 0, 0] [1, 2, 3, 4]
```
(2)接著找一條能從左上到右下的路徑, 路徑的最小值要最大越好, 所以用binary search來猜最大值
最後的最大值就是code裡的right了
但因為我們是1-indexed, 題目是0-indexed, 所以最後要-1
TC: (1): BFS = $n^2$, (2): BFS & Binary Search = $n^2logn$
Total TC: $n^2 + n^2logn$ = $n^2logn$
p.s. 官神的code裡在binary search時是0 ~ 2n, 但其實0 ~ n就可以了, 因為起點或終點一定<= n