一、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:因爲任意兩個數之間不能是相鄰的,如果相鄰位置就是最小,那麼除去這個最小以外的數,也能保證取到的是最小。
複雜度分析
- 時間複雜度:,
- 空間複雜度:,