返回介绍

solution / 2000-2099 / 2017.Grid Game / README

发布于 2024-06-17 01:03:12 字数 4890 浏览 0 评论 0 收藏 0

2017. 网格游戏

English Version

题目描述

给你一个下标从 0 开始的二维数组 grid ,数组大小为 2 x n ,其中 grid[r][c] 表示矩阵中 (r, c) 位置上的点数。现在有两个机器人正在矩阵上参与一场游戏。

两个机器人初始位置都是 (0, 0) ,目标位置是 (1, n-1) 。每个机器人只会 向右 ((r, c)(r, c + 1)) 或 向下 ((r, c)(r + 1, c)) 。

游戏开始,第一个 机器人从 (0, 0) 移动到 (1, n-1) ,并收集路径上单元格的全部点数。对于路径上所有单元格 (r, c) ,途经后 grid[r][c] 会重置为 0 。然后,第二个 机器人从 (0, 0) 移动到 (1, n-1) ,同样收集路径上单元的全部点数。注意,它们的路径可能会存在相交的部分。

第一个 机器人想要打击竞争对手,使 第二个 机器人收集到的点数 最小化 。与此相对,第二个 机器人想要 最大化 自己收集到的点数。两个机器人都发挥出自己的 最佳水平 的前提下,返回 第二个 机器人收集到的 点数 _。_

 

示例 1:

输入:grid = [[2,5,4],[1,5,1]]
输出:4
解释:第一个机器人的最佳路径如红色所示,第二个机器人的最佳路径如蓝色所示。
第一个机器人访问过的单元格将会重置为 0 。
第二个机器人将会收集到 0 + 0 + 4 + 0 = 4 个点。

示例 2:

输入:grid = [[3,3,1],[8,5,2]]
输出:4
解释:第一个机器人的最佳路径如红色所示,第二个机器人的最佳路径如蓝色所示。 
第一个机器人访问过的单元格将会重置为 0 。
第二个机器人将会收集到 0 + 3 + 1 + 0 = 4 个点。

示例 3:

输入:grid = [[1,3,1,15],[1,3,3,1]]
输出:7
解释:第一个机器人的最佳路径如红色所示,第二个机器人的最佳路径如蓝色所示。
第一个机器人访问过的单元格将会重置为 0 。
第二个机器人将会收集到 0 + 1 + 3 + 3 + 0 = 7 个点。

 

提示:

  • grid.length == 2
  • n == grid[r].length
  • 1 <= n <= 5 * 104
  • 1 <= grid[r][c] <= 105

解法

方法一:前缀和

我们注意到,如果确定了第一个机器人拐头向下的位置 $j$,那么第二个机器人的最优路径也就确定了,第二个机器人的最优路径就是第一行从 $j+1$ 到 $n-1$ 的前缀和,或者第二行从 $0$ 到 $j-1$ 的前缀和,取两者的最大值。

我们先计算第一行的后缀点数和,记为 $s_1$,第二行的前缀点数和记为 $s_2$,初始时 $s_1 = \sum_{j=0}^{n-1} grid[0][j]$, $s_2 = 0$。

然后我们枚举第一个机器人拐头向下的位置 $j$,此时更新 $s_1 = s_1 - grid[0][j]$, 那么第二个机器人的最优路径和就是 $max(s_1, s_2)$,我们取所有 $j$ 对应的 $max(s_1, s_2)$ 的最小值即可。然后更新 $s_2 = s_2 + grid[1][j]$。

枚举结束后,返回答案即可。

时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 是网格的列数。

class Solution:
  def gridGame(self, grid: List[List[int]]) -> int:
    ans = inf
    s1, s2 = sum(grid[0]), 0
    for j, v in enumerate(grid[0]):
      s1 -= v
      ans = min(ans, max(s1, s2))
      s2 += grid[1][j]
    return ans
class Solution {
  public long gridGame(int[][] grid) {
    long ans = Long.MAX_VALUE;
    long s1 = 0, s2 = 0;
    for (int v : grid[0]) {
      s1 += v;
    }
    int n = grid[0].length;
    for (int j = 0; j < n; ++j) {
      s1 -= grid[0][j];
      ans = Math.min(ans, Math.max(s1, s2));
      s2 += grid[1][j];
    }
    return ans;
  }
}
using ll = long long;

class Solution {
public:
  long long gridGame(vector<vector<int>>& grid) {
    ll ans = LONG_MAX;
    int n = grid[0].size();
    ll s1 = 0, s2 = 0;
    for (int& v : grid[0]) s1 += v;
    for (int j = 0; j < n; ++j) {
      s1 -= grid[0][j];
      ans = min(ans, max(s1, s2));
      s2 += grid[1][j];
    }
    return ans;
  }
};
func gridGame(grid [][]int) int64 {
  ans := math.MaxInt64
  s1, s2 := 0, 0
  for _, v := range grid[0] {
    s1 += v
  }
  for j, v := range grid[0] {
    s1 -= v
    ans = min(ans, max(s1, s2))
    s2 += grid[1][j]
  }
  return int64(ans)
}
function gridGame(grid: number[][]): number {
  let ans = Number.MAX_SAFE_INTEGER;
  let s1 = grid[0].reduce((a, b) => a + b, 0);
  let s2 = 0;
  for (let j = 0; j < grid[0].length; ++j) {
    s1 -= grid[0][j];
    ans = Math.min(ans, Math.max(s1, s2));
    s2 += grid[1][j];
  }
  return ans;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文