题目描述
在一个二维平面上,有一个 n x m 的网格,每个格子有一个非负整数。你从左上角 (0, 0) 开始,每次只能向右或向下移动,目标是到达右下角 (n-1, m-1)。
在移动过程中,你需要记录经过的格子中,最大数字与最小数字的差的最小值。
输入:
- 第一行包含两个整数 n 和 m,表示网格的行数和列数。
- 接下来的 n 行,每行包含 m 个整数,表示网格中每个格子的值。
输出:
- 输出一个整数,表示从左上角到右下角路径中,最大数字与最小数字的差的最小值。
限制条件:
- 1 <= n, m <= 500
- 0 <= grid[i][j] <= 10^9
思路分析
这个问题可以转化为求从左上角到右下角路径中的最大值和最小值,并计算它们的差值。我们可以使用动态规划(Dynamic Programming, DP)来求解这个问题。
- 定义状态:
- maxDP[i][j] 表示从 (0, 0) 到 (i, j) 路径中的最大值。
- minDP[i][j] 表示从 (0, 0) 到 (i, j) 路径中的最小值。
- 状态转移:
- maxDP[i][j] = max(maxDP[i-1][j], maxDP[i][j-1], grid[i][j])
- minDP[i][j] = min(minDP[i-1][j], minDP[i][j-1], grid[i][j])
- 初始化:
- maxDP[0][0] = grid[0][0]
- minDP[0][0] = grid[0][0]
- 计算最终结果:
- 遍历整个 maxDP 和 minDP 数组,计算 maxDP[i][j] - minDP[i][j] 的最小值。
Java 代码解析
public class JumpGrid {
public static int minDifference(int[][] grid) {
int n = grid.length;
int m = grid[0].length;
int[][] maxDP = new int[n][m];
int[][] minDP = new int[n][m];
maxDP[0][0] = grid[0][0];
minDP[0][0] = grid[0][0];
for (int i = 1; i < n; i++) {
maxDP[i][0] = Math.max(maxDP[i-1][0], grid[i][0]);
minDP[i][0] = Math.min(minDP[i-1][0], grid[i][0]);
}
for (int j = 1; j < m; j++) {
maxDP[0][j] = Math.max(maxDP[0][j-1], grid[0][j]);
minDP[0][j] = Math.min(minDP[0][j-1], grid[0][j]);
}
for (int i = 1; i < n; i++) {
for (int j = 1; j < m; j++) {
maxDP[i][j] = Math.max(maxDP[i-1][j], Math.max(maxDP[i][j-1], grid[i][j]));
minDP[i][j] = Math.min(minDP[i-1][j], Math.min(minDP[i][j-1], grid[i][j]));
}
}
int minDiff = Integer.MAX_VALUE;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
minDiff = Math.min(minDiff, maxDP[i][j] - minDP[i][j]);
}
}
return minDiff;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
int[][] grid = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
grid[i][j] = scanner.nextInt();
}
}
System.out.println(minDifference(grid));
}
}
C++ 代码解析
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;
int minDifference(vector<vector<int>>& grid) {
int n = grid.size();
int m = grid[0].size();
vector<vector<int>> maxDP(n, vector<int>(m));
vector<vector<int>> minDP(n, vector<int>(m));
maxDP[0][0] = grid[0][0];
minDP[0][0] = grid[0][0];
for (int i = 1; i < n; i++) {
maxDP[i][0] = max(maxDP[i-1][0], grid[i][0]);
minDP[i][0] = min(minDP[i-1][0], grid[i][0]);
}
for (int j = 1; j < m; j++) {
maxDP[0][j] = max(maxDP[0][j-1], grid[0][j]);
minDP[0][j] = min(minDP[0][j-1], grid[0][j]);
}
for (int i = 1; i < n; i++) {
for (int j = 1; j < m; j++) {
maxDP[i][j] = max({maxDP[i-1][j], maxDP[i][j-1], grid[i][j]});
minDP[i][j] = min({minDP[i-1][j], minDP[i][j-1], grid[i][j]});
}
}
int minDiff = INT_MAX;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
minDiff = min(minDiff, maxDP[i][j] - minDP[i][j]);
}
}
return minDiff;
}
int main() {
int n, m;
cin >> n >> m;
vector<vector<int>> grid(n, vector<int>(m));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> grid[i][j];
}
}
cout << minDifference(grid) << endl;
return 0;
}
Python 代码解析
def min_difference(grid):
n = len(grid)
m = len(grid[0])
max_dp = [[0] * m for _ in range(n)]
min_dp = [[0] * m for _ in range(n)]
max_dp[0][0] = grid[0][0]
min_dp[0][0] = grid[0][0]
for i in range(1, n):
max_dp[i][0] = max(max_dp[i-1][0], grid[i][0])
min_dp[i][0] = min(min_dp[i-1][0], grid[i][0])
for j in range(1, m):
max_dp[0][j] = max(max_dp[0][j-1], grid[0][j])
min_dp[0][j] = min(min_dp[0][j-1], grid[0][j])
for i in range(1, n):
for j in range(1, m):
max_dp[i][j] = max(max_dp[i-1][j], max_dp[i][j-1], grid[i][j])