# 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