classSolution: defminimumTime(self, grid: List[List[int]]) -> int: m, n = len(grid), len(grid[0]) if grid[0][1] > 1and grid[1][0] > 1: # 无法「等待」 return -1
dis = [[inf] * n for _ inrange(m)] dis[0][0] = 0 h = [(0, 0, 0)] whileTrue: # 可以等待,就一定可以到达终点 d, i, j = heappop(h) if d > dis[i][j]: continue if i == m - 1and j == n - 1: # 找到终点,此时 d 一定是最短路 return d for x, y in (i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1): # 枚举周围四个格子 if0 <= x < m and0 <= y < n: nd = max(d + 1, grid[x][y]) nd += (nd - x - y) % 2# nd 必须和 x+y 同奇偶 if nd < dis[x][y]: dis[x][y] = nd # 更新最短路 heappush(h, (nd, x, y))
classSolution: defminimumTime(self, grid: List[List[int]]) -> int: m, n = len(grid), len(grid[0]) if grid[0][1] > 1and grid[1][0] > 1: # 无法「等待」 return -1
vis = [[-inf] * n for _ inrange(m)] defcheck(end_time: int) -> bool: vis[-1][-1] = end_time q = [(m - 1, n - 1)] t = end_time - 1 while q: tmp = q q = [] for i, j in tmp: for x, y in (i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1): # 枚举周围四个格子 if0 <= x < m and0 <= y < n and vis[x][y] != end_time and grid[x][y] <= t: if x == 0and y == 0: returnTrue vis[x][y] = end_time # 用二分的值来标记,避免重复创建 vis 数组 q.append((x, y)) t -= 1 returnFalse
left = max(grid[-1][-1], m + n - 2) - 1 right = max(map(max, grid)) + m + n # 开区间 while left + 1 < right: mid = (left + right) // 2 if check(mid): right = mid else: left = mid return right + (right - m - n) % 2
classSolution { staticconstexprint dirs[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; public: intminimumTime(vector<vector<int>> &grid){ int m = grid.size(), n = grid[0].size(); if (grid[0][1] > 1 && grid[1][0] > 1) // 无法「等待」 return-1;
int vis[m][n]; memset(vis, -1, sizeof(vis)); auto check = [&](int end_time) -> bool { vis[m - 1][n - 1] = end_time; vector<pair<int, int>> q = { {m - 1, n - 1} }; for (int t = end_time - 1; !q.empty(); --t) { vector<pair<int, int>> nxt; for (auto &[i, j] : q) { for (auto &d : dirs) { // 枚举周围四个格子 int x = i + d[0], y = j + d[1]; if (0 <= x && x < m && 0 <= y && y < n && vis[x][y] != end_time && grid[x][y] <= t) { if (x == 0 && y == 0) returntrue; vis[x][y] = end_time; // 用二分的值来标记,避免重复创建 vis 数组 nxt.emplace_back(x, y); } } } q = move(nxt); } returnfalse; };
int left = max(grid.back().back(), m + n - 2) - 1, right = 1e5 + m + n; // 开区间 while (left + 1 < right) { int mid = left + (right - left) / 2; (check(mid) ? right : left) = mid; } return right + (right + m + n) % 2; } };