给你一个 R 行 C 列的整数矩阵 A。矩阵上的路径从 [0,0] 开始,在 [R-1,C-1] 结束。
路径沿四个基本方向(上、下、左、右)展开,从一个已访问单元格移动到任一相邻的未访问单元格。
路径的得分是该路径上的 最小 值。例如,路径 8 → 4 → 5 → 9 的值为 4 。
找出所有路径中得分 最高 的那条路径,返回其 得分。
示例 1:
输入:[[5,4,5],[1,2,6],[7,4,6]]
输出:4
解释:
得分最高的路径用黄色突出显示。
示例 2:
输入:[[2,2,1,2,2,2],[1,2,2,2,1,2]]
输出:2
示例 3:
输入:[[3,4,6,3,4],[0,2,1,1,7],[8,8,3,2,7],[3,2,4,9,8],[4,1,2,0,0],[4,6,5,4,3]]
输出:3
提示:
1 <= R, C <= 100
0 <= A[i][j] <= 10^9
本题每一步做决策的过程实际上可以理解为,在能走的范围内,走使得路径分数尽可能大的点,也就是说可以抽象成在一个优先级队列找最大值的过程。
以示例1为例:
一开始从点(0, 0)
出发,起始分数为5
。
可以走的路有两条:
往右到点(0, 1)
,走这条会使得路径的分数变成4 = min(5, 4)
, 其中5
是从起点到当前点的分数,4
是下一个点的值
往下到点(1, 0)
,走这条会使得路径的分数变成1 = min(5, 1)
选哪条呢,显然为了实现让路径最小值尽可能大的题目目标,我们应该选择往右走到点(1, 0)
。
到达4之后,又多了两个选择:
(2, 0)
, 分数还是4 = min(4, 5)
(1, 1)
,分数变为2 = min(4, 2)
目前可选的点有三个,分别会让其所在的路径的分数变成4
, 2
和1
, 因而选择最大的4,即往右走到达点(2, 0)
以此类推,每次选择前往 能使所在路径分数尽可能大的点,当到达终点时,返回分数即可。
class Solution(object):
def maximumMinimumPath(self, A):
"""
:type A: List[List[int]]
:rtype: int
"""
from heapq import *
if not A or not A[0]:
return 0
m, n = len(A), len(A[0])
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]
queue = [[-A[0][0], 0, 0]] #Python默认最小堆,因此需要手动用相反数实现最大堆……
visited = set([0,0])
heapify(queue)
while queue:
score, x0, y0 = heappop(queue) #把目前队里最优的点找出来,三个值分别代表分数, X坐标, Y坐标
if [x0, y0] == [m - 1, n - 1]: #如果已经到终点了
return -score #输出结果时记得再取一次相反数
for k in range(4): #找四个可能的邻居点
x = x0 + dx[k]
y = y0 + dy[k]
if 0 <= x < m and 0 <= y < n and (x, y) not in visited:#邻居点可走
visited.add((x, y))
heappush(queue, [max(score, -A[x][y]), x, y]) #邻居点入队,调整分数,因为取了相反数所以找最小值用max不用min
时间复杂度: O ( M N ) O(MN) O(MN)
空间复杂度: O ( M N ) O(MN) O(MN)