一、Problem
Given a square grid of integers arr, a falling path with non-zero shifts is a choice of exactly one element from each row of arr, such that no two elements chosen in adjacent rows are in the same column.
Return the minimum sum of a falling path with non-zero shifts.
Input: arr = [[1,2,3],[4,5,6],[7,8,9]]
Output: 13
Explanation:
The possible falling paths are:
[1,5,9], [1,5,7], [1,6,7], [1,6,8],
[2,4,8], [2,4,9], [2,6,7], [2,6,8],
[3,4,8], [3,4,9], [3,5,7], [3,5,9]
The falling path with the smallest sum is [1,5,7], so the answer is 13.
Constraints:
1 <= arr.length == arr[i].length <= 200
-99 <= arr[i][j] <= 99
二、Solution
方法一:暴力 dp
- 定义状态:
- 第 行选第 个数时的最小路径和
- 思考初始化:
- 思考状态转移方程:
- 表示位置 的值由上一行的最小路径和 + 当前位置的值组成。
- 思考输出:
这是比较暴力的 dp…
class Solution {
public int minFallingPathSum(int[][] A) {
int n = A.length, INF = 0x3f3f3f3f, f[][] = new int[n][n];
for (int j = 0; j < n; j++) f[0][j] = A[0][j];
for (int i = 1; i < n; i++)
for (int j = 0; j < n; j++) {
int lastMin = INF;
for (int k = 0; k < n; k++) if (k != j && f[i-1][k] < lastMin) {
lastMin = f[i-1][k];
}
f[i][j] = A[i][j] + lastMin;
}
int min = INF;
for (int j = 0; j < n; j++) if (f[n-1][j] < min) {
min = f[n-1][j];
}
return min;
}
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,
方法二:
上面的代码用了 的时间去寻找上一行的最小路径和,其实可以在 for(int j) 同级的地方预处理上一行的最小值到缓存数组中,这就是典型的用空间换取时间。
class Solution {
int INF = 0x3f3f3f3f, n;
int[] lastMinArr(int[][] f, int i) {
int min = INF, sec = INF, mini = 0;
for (int j = 0; j < n; j++) if (f[i][j] < min) {
min = f[i][j];
mini = j;
}
for (int j = 0; j < n; j++) if (j != mini && f[i][j] < sec) {
sec = f[i][j];
}
int[] a = new int[n];
for (int j = 0; j < n; j++) {
if (j == mini) a[j] = sec;
else a[j] = min;
}
return a;
}
public int minFallingPathSum(int[][] A) {
n = A.length;
int f[][] = new int[n][n];
for (int j = 0; j < n; j++) f[0][j] = A[0][j];
int[] a = lastMinArr(f, 0);
for (int i = 1; i < n; i++) {
for (int j = 0; j < n; j++) {
f[i][j] = A[i][j] + a[j];
}
a = lastMinArr(f, i);
}
int min = INF;
for (int j = 0; j < n; j++) if (f[n-1][j] < min) {
min = f[n-1][j];
}
return min;
}
}
Q:为什么在求 lastMinArr 时,需要把 sec 和 min 的位置交换过来?直接数组的所有值都替换为 min 不好吗?
A:因为任意两个数之间不能是相邻的,如果相邻位置就是最小,那么除去这个最小以外的数,也能保证取到的是最小。
复杂度分析
- 时间复杂度:,
- 空间复杂度:,