LeetCode 题解工作台
你能穿过矩阵的最后一天
给你一个下标从 1 开始的二进制矩阵,其中 0 表示陆地, 1 表示水域。同时给你 row 和 col 分别表示矩阵中行和列的数目。 一开始在第 0 天, 整个 矩阵都是 陆地 。但每一天都会有一块新陆地被 水 淹没变成水域。给你一个下标从 1 开始的二维数组 cells ,其中 cells[i] …
6
题型
6
代码语言
3
相关题
当前训练重点
困难 · 二分·搜索·答案·空间
答案摘要
我们注意到,如果我们能在第 天从最上面一行走到最下面一行,那么对于任意 $0 \lt k' \lt k$,我们也能在第 天从最上面一行走到最下面一行。这存在着单调性,因此,我们可以使用二分查找,找到最大的 ,使得我们能在第 天从最上面一行走到最下面一行。 我们定义二分查找的左边界 $l = 1$,右边界 $r = |cells|$,其中 表示数组 的长度。然后,我们二分枚举 ,对于每一个…
Interview AiBoxInterview AiBox 实时 AI 助手,陪你讲清 二分·搜索·答案·空间 题型思路
题目描述
给你一个下标从 1 开始的二进制矩阵,其中 0 表示陆地,1 表示水域。同时给你 row 和 col 分别表示矩阵中行和列的数目。
一开始在第 0 天,整个 矩阵都是 陆地 。但每一天都会有一块新陆地被 水 淹没变成水域。给你一个下标从 1 开始的二维数组 cells ,其中 cells[i] = [ri, ci] 表示在第 i 天,第 ri 行 ci 列(下标都是从 1 开始)的陆地会变成 水域 (也就是 0 变成 1 )。
你想知道从矩阵最 上面 一行走到最 下面 一行,且只经过陆地格子的 最后一天 是哪一天。你可以从最上面一行的 任意 格子出发,到达最下面一行的 任意 格子。你只能沿着 四个 基本方向移动(也就是上下左右)。
请返回只经过陆地格子能从最 上面 一行走到最 下面 一行的 最后一天 。
示例 1:
输入:row = 2, col = 2, cells = [[1,1],[2,1],[1,2],[2,2]] 输出:2 解释:上图描述了矩阵从第 0 天开始是如何变化的。 可以从最上面一行到最下面一行的最后一天是第 2 天。
示例 2:
输入:row = 2, col = 2, cells = [[1,1],[1,2],[2,1],[2,2]] 输出:1 解释:上图描述了矩阵从第 0 天开始是如何变化的。 可以从最上面一行到最下面一行的最后一天是第 1 天。
示例 3:
输入:row = 3, col = 3, cells = [[1,2],[2,1],[3,3],[2,2],[1,1],[1,3],[2,3],[3,2],[3,1]] 输出:3 解释:上图描述了矩阵从第 0 天开始是如何变化的。 可以从最上面一行到最下面一行的最后一天是第 3 天。
提示:
2 <= row, col <= 2 * 1044 <= row * col <= 2 * 104cells.length == row * col1 <= ri <= row1 <= ci <= colcells中的所有格子坐标都是 唯一 的。
解题思路
方法一:二分查找 + BFS
我们注意到,如果我们能在第 天从最上面一行走到最下面一行,那么对于任意 ,我们也能在第 天从最上面一行走到最下面一行。这存在着单调性,因此,我们可以使用二分查找,找到最大的 ,使得我们能在第 天从最上面一行走到最下面一行。
我们定义二分查找的左边界 ,右边界 ,其中 表示数组 的长度。然后,我们二分枚举 ,对于每一个 ,我们取 的前 个元素,将这些元素对应的格子变成水域,然后使用广度优先搜索,从最上面一行开始,尝试走到最下面一行。如果我们能走到最下面一行,那么说明我们可以在第 天从最上面一行走到最下面一行,我们就将左边界 更新为 ,否则,我们将右边界 更新为 。
时间复杂度 ,空间复杂度 。其中 和 分别表示矩阵的行数和列数。
class Solution:
def latestDayToCross(self, row: int, col: int, cells: List[List[int]]) -> int:
def check(k: int) -> bool:
g = [[0] * col for _ in range(row)]
for i, j in cells[:k]:
g[i - 1][j - 1] = 1
q = [(0, j) for j in range(col) if g[0][j] == 0]
for x, y in q:
if x == row - 1:
return True
for a, b in pairwise(dirs):
nx, ny = x + a, y + b
if 0 <= nx < row and 0 <= ny < col and g[nx][ny] == 0:
q.append((nx, ny))
g[nx][ny] = 1
return False
n = row * col
l, r = 1, n
dirs = (-1, 0, 1, 0, -1)
while l < r:
mid = (l + r + 1) >> 1
if check(mid):
l = mid
else:
r = mid - 1
return l
复杂度分析
| 指标 | 值 |
|---|---|
| 时间 | Depends on the final approach |
| 空间 | Depends on the final approach |
面试官常问的追问
外企场景- question_mark
Candidate demonstrates an understanding of binary search and how to apply it to a range of possible answers.
- question_mark
Candidate applies BFS/DFS to verify paths through a grid, indicating solid knowledge of graph traversal algorithms.
- question_mark
Candidate identifies optimization opportunities through binary search, showing problem-solving skills in narrowing down search spaces.
常见陷阱
外企场景- error
Failing to optimize the search space by not using binary search on the valid days.
- error
Incorrect path validation by using inefficient graph traversal techniques or not accounting for the matrix's changing state over days.
- error
Overcomplicating the solution with unnecessary checks or missing edge cases like when the matrix is fully flooded.
进阶变体
外企场景- arrow_right_alt
Use Union-Find to handle connectivity checks across the matrix during water flooding.
- arrow_right_alt
Apply dynamic programming or memoization to speed up the path search process for each day.
- arrow_right_alt
Solve the problem by iterating through all days and performing BFS/DFS for each day, though less optimal than binary search.