Minimum Falling Path Sum
Problem
A falling path starts at any number in the first row. From a number at column j you may step to the row below at column j - 1, j or j + 1 (inside the matrix). Print the smallest possible sum of the numbers on a path from the first row to the last row.
Constraints
- 1 <= r, c <= 100
- the brute-force version is only for r <= 12
Examples
Input
3 3 2 1 3 6 5 4 7 8 9
Output
13
Solutions
Each cell only needs the three cells above it. So we keep one row of answers and build the next row from it. Every cell is computed once: O(r c).
/*
* Problem : Smallest falling path.
* Input : r, c and the rows.
* Output : The smallest sum.
* Approach: Row by row table
* Time : O(r c)
* Space : O(c)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static long solve(int[][] m) {
int cols = m[0].length;
// Step 1: best[j] is the smallest sum of a path that ends at column j of the current row. The first row starts the paths.
long[] best = new long[cols];
for (int j = 0; j < cols; j++) {
best[j] = m[0][j];
}
for (int i = 1; i < m.length; i++) {
long[] next = new long[cols];
for (int j = 0; j < cols; j++) {
// Step 2: A path comes from the left, above or right cell of the row above. Take the smallest.
long from = best[j];
if (j > 0) {
from = Math.min(from, best[j - 1]);
}
if (j < cols - 1) {
from = Math.min(from, best[j + 1]);
}
next[j] = from + m[i][j];
}
best = next;
}
// Step 3: The path can end in any column of the last row.
long answer = best[0];
for (long value : best) {
answer = Math.min(answer, value);
}
return answer;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int rows = scanner.nextInt();
int cols = scanner.nextInt();
int[][] m = new int[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m[i][j] = scanner.nextInt();
}
}
System.out.println(solve(m));
}
}
Hints (1)
- Which three cells can come before a cell?