LeetCode 3148. 矩阵中的最大得分

3148. 矩阵中的最大得分

给你一个由 正整数 组成、大小为 m x n 的矩阵 grid。你可以从矩阵中的任一单元格移动到另一个位于正下方或正右侧的任意单元格(不必相邻)。从值为 c1 的单元格移动到值为 c2 的单元格的得分为 c2 - c1 。

你可以从 任一 单元格开始,并且必须至少移动一次。

返回你能得到的 最大 总得分。

示例 1:

输入:grid = [[9,5,7,3],[8,9,6,1],[6,7,14,3],[2,5,3,1]]

输出:9

解释:从单元格 (0, 1) 开始,并执行以下移动:
- 从单元格 (0, 1) 移动到 (2, 1),得分为 7 - 5 = 2 。
- 从单元格 (2, 1) 移动到 (2, 2),得分为 14 - 7 = 7 。
总得分为 2 + 7 = 9 。

示例 2:

输入:grid = [[4,3,2],[3,2,1]]

输出:-1

解释:从单元格 (0, 0) 开始,执行一次移动:从 (0, 0) 到 (0, 1) 。得分为 3 - 4 = -1 。

提示:

  • m == grid.length
  • n == grid[i].length
  • 2 <= m, n <= 1000
  • 4 <= m * n <= 10^5
  • 1 <= grid[i][j] <= 10^5

提示 1

Any path from a cell (x1, y1) to another cell (x2, y2) will always have a score of grid[x2][y2] - grid[x1][y1].


提示 2

Let’s say we fix the starting cell (x1, y1), how to the find a cell (x2, y2) such that the value grid[x2][y2] - grid[x1][y1] is the maximum possible?

 

解法:动态规划

把 grid[i][j] 视作海拔高度,题目要计算的是重力势能的变化量之和,也就是终点和起点的海拔高度之差。

枚举终点海拔高度,那么起点海拔高度越小越好,且起点只能在 (i,j) 的左上方向(可以是正左或者正上)。

定义 dp[i+1][j+1] 表示左上角在 (0,0),右下角在 (i,j) 的子矩阵的最小值。

类似二维前缀和,我们有

dp[i+1][j+1]=min(dp[i+1][j],dp[i][j+1],grid[i][j])
注意起点终点不能重合,如果终点在 (i,j),那么起点的最小值为

min(dp[i+1][j],dp[i][j+1])
取终点起点之差的最大值,即为答案。

同类题型:LeetCode 221. 最大正方形-CSDN博客 LeetCode 1277. 统计全为 1 的正方形子矩阵-CSDN博客

Java版:

class Solution {
    public int maxScore(List<List<Integer>> grid) {
        int ans = Integer.MIN_VALUE;
        int m = grid.size();
        int n = grid.get(0).size();
        int[][] dp = new int[m + 1][n + 1];
        Arrays.fill(dp[0], Integer.MAX_VALUE);
        for (int i = 0; i < m; i++) {
            dp[i + 1][0] = Integer.MAX_VALUE;
            for (int j = 0; j < n; j++) {
                dp[i + 1][j + 1] = Math.min(Math.min(dp[i + 1][j], dp[i][j + 1]), grid.get(i).get(j));
                ans = Math.max(ans, grid.get(i).get(j) - Math.min(dp[i + 1][j], dp[i][j + 1]));
            }
        } 
        return ans;
    }
}

 Python3版:

class Solution:
    def maxScore(self, grid: List[List[int]]) -> int:
        ans = -inf
        m = len(grid)
        n = len(grid[0])
        dp = [[inf] * (n + 1) for _ in range(m + 1)]
        for i in range(m):
            for j in range(n):
                dp[i + 1][j + 1] = min(dp[i + 1][j], dp[i][j + 1], grid[i][j])
                ans = max(ans, grid[i][j] - min(dp[i + 1][j], dp[i][j + 1]))
        return ans
复杂度分析
  • 时间复杂度:O(mn),其中 m 和 n 分别为 mat 的行数和列数。
  • 空间复杂度:O(mn)。
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值