LeetCode-Python-1102. 得分最高的路径

660 篇文章 23 订阅

给你一个 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

可以走的路有两条:

  1. 往右到点(0, 1),走这条会使得路径的分数变成4 = min(5, 4), 其中5是从起点到当前点的分数,4是下一个点的值

  2. 往下到点(1, 0),走这条会使得路径的分数变成1 = min(5, 1)

选哪条呢,显然为了实现让路径最小值尽可能大的题目目标,我们应该选择往右走到点(0, 1)

到达4之后,又多了两个选择:

  1. 往右到点(2, 0), 分数还是4 = min(4, 5)
  2. 往下到点(1, 1),分数变为2 = min(4, 2)

目前可选的点有三个,分别会让其所在的路径的分数变成421, 因而选择最大的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 L o g ( M N ) ) O(MNLog(MN)) OMNLogMN

空间复杂度: O ( M N ) O(MN) OMN

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值