目录
题目:
给你一个下标从 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) ,同样收集路径上单元的全部点数。注意,它们的路径可能会存在相交的部分。
第一个 机器人想要打击竞争对手,使 第二个 机器人收集到的点数 最小化 。与此相对,第二个 机器人想要 最大化 自己收集到的点数。两个机器人都发挥出自己的 最佳水平 的前提下,返回 第二个 机器人收集到的 点数 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/grid-game
思路:
这道题看上去好像很复杂,其实我们可以将其简化,因为第一个机器人一定走的是一个(Z型的路线,期限情况是L和L的变形)。这样的话,剩下的格子就是左下和右上的部分。而我们要得到的是最小值(这个最小值同时是第一个机器人走完后,第二个机器人能走的最大值)。
到这里我们的问题就很简单了。
方案1:我们假设左下0个,右上从grid[0][1]到grid[0][length-1],然后求出左下的和(0)和右上的和取最大值赋给结果。然后左下右边多一位,右上左边少一位,在求二者最大,如果这个值小,则更新结果。
方案2:因为我们要得到最小的“两数中的最大值”,所以我们不能有一个数特别大,因此我们可以考虑:
1.先让左下和右上都不去(索引指向-1和grid[0].length)
2.然后判断移动左下向右移的结果和右上向左移的结果,哪个更小就移动哪个,这样可以保证此时移动一下之后的最大值最小。
3.重复2的操作,指导两个的指针(左下最右一个,右上最左一个)差为2。
代码:
方案1:
package LiKouZhouSai;
public class Day9_26_2 {
public static void main(String[] args) {
Solution26_2 solution26_2=new Solution26_2();
int[][] grid={{1,3,1,15},{1,3,3,1}};
System.out.println(solution26_2.gridGame(grid));
}
}
class Solution26_2 {
public long gridGame(int[][] grid) {
long front=0;
long end=0;
for(int i=1;i<grid[0].length;i++){
end+=grid[0][i];
}
long temp;
long result=Math.max(front,end);
for(int i=0;i<grid[1].length-1;i++){
front=front+grid[1][i];
end=end-grid[0][i+1];
temp=Math.max(front,end);
if(temp<result){
result=temp;
}
}
return result;
}
}
方案2:
package LiKouZhouSai;
public class Day9_26_2_2 {
public static void main(String[] args) {
Solution26_2_2 solution26_2_2=new Solution26_2_2();
System.out.println(solution26_2_2.gridGame(new int[][]{{1,3,1,15},{1,3,3,1}}));
}
}
class Solution26_2_2 {
public long gridGame(int[][] grid) {
long front=0;
long end=0;
int indexF=-1;
int indexE=grid[0].length;
while(indexE-indexF>2){
long tempF=front+grid[1][indexF+1];
long tempE=end+grid[0][indexE-1];
if(tempF<tempE){
indexF++;
front+=grid[1][indexF];
}else{
indexE--;
end+=grid[0][indexE];
}
}
return Math.max(front,end);
}
}