Skip to content

Commit af265ef

Browse files
committed
Add problem 2 based on DP
1 parent 001f60d commit af265ef

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed

Minimum Falling Path Sum/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Minimum Falling Path Sum
2+
[Try the problem](https://leetcode.com/problems/minimum-falling-path-sum/)
3+
4+
Given a matrix of integers, we want to find the **minimum** sum of *falling path* through it.
5+
6+
A falling path starts at any element in the first row, and chooses one element from each row.
7+
<br/>
8+
The next row's choice must be in a column that is different from the previous row's column by atmost one.
9+
10+
### Example
11+
12+
```
13+
Input: [[1,2,3],[4,5,6],[7,8,9]]
14+
Output: 12
15+
Explanation:
16+
The possible falling paths are:
17+
```
18+
19+
- `[1,4,7], [1,4,8], [1,5,7], [1,5,8], [1,5,9]`
20+
- `[2,4,7], [2,4,8], [2,5,7], [2,5,8], [2,5,9], [2,6,8], [2,6,9]`
21+
- `[3,5,7], [3,5,8], [3,5,9], [3,6,8], [3,6,9]`
22+
23+
The falling path with the smallest sum is `[1,4,7]`, so the answer is `12`.

Minimum Falling Path Sum/solution.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include <iostream>
2+
#include <vector>
3+
4+
using namespace std;
5+
class Solution {
6+
public:
7+
int minFallingPathSum(vector<vector<int> > &A) {
8+
int rows = A.size(); // 3
9+
int cols = A[0].size(); // 3
10+
vector<vector<int> > minSum(rows, vector<int> (cols, 0)); // 3*3 with all 0's
11+
// set for first row
12+
for (int curCol = 0; curCol <cols; ++curCol) {
13+
minSum[0][curCol] = A[0][curCol]; // {1, 2, 3} is the first row
14+
}
15+
// solve for all other rows, value depends on top, topleft and topright
16+
for (int curRow = 1; curRow < rows; ++curRow) {
17+
for (int curCol = 0; curCol < cols; ++curCol) {
18+
int curMinSum = INT_MAX;
19+
int prevRow = curRow - 1;
20+
for (int k = -1; k <= 1; ++k) {
21+
int prevCol = curCol + k;
22+
if (prevCol >= 0 && prevCol < cols) {
23+
curMinSum = min(curMinSum, minSum[prevRow][prevCol]);
24+
}
25+
}
26+
// curMinSum is 1 for the cell valued 4, i.e. (1, 0)
27+
minSum[curRow][curCol] = A[curRow][curCol] + curMinSum;
28+
// minSum[1][0] = 4 + 1 = 5
29+
}
30+
}
31+
// minSum at the end = { {1, 2, 3}, {5, 6, 8}, {12, 13, 15} }
32+
// result is the minimum value in the last row
33+
int res = INT_MAX;
34+
for (int curCol = 0; curCol < cols; ++curCol) {
35+
res = min(res, minSum[rows - 1][curCol]);
36+
}
37+
return res; // 12
38+
}
39+
};
40+
41+
int main () {
42+
Solution solver;
43+
vector<vector<int> > A = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
44+
cout << solver.minFallingPathSum(A) << endl;
45+
}

Minimum Falling Path Sum/solution.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
Initially, thinking of trying all possibilities as a naive and brute force solution to start with.
2+
3+
Trying to realize its complexity, thinking it around O(N*3^(N-1)) as can start with any
4+
element in the first row and then for any element can go to around 3 other elements in the
5+
next row.
6+
7+
Trying to think how to optimize this approach, the observation is once we are at a particular
8+
element in a row, the only think that matters now is the element in the next row, the path to
9+
reach that element doesn't really matter.
10+
11+
So, its kind of an overlapping subproblem since we can reach that point from atmost 3 points above
12+
that element, but need to now solve the same problem.
13+
14+
Also, another observation is that we are ultimately going to end at the last row, in some column.
15+
So, if we can consider minSum[i][j] denoting the minimum sum to reach the element (i, j)
16+
following the conditions given, then our answer is simply the minimum of all the values
17+
minSum[i][j] in the last row, i.e. i = Index of last row, j ranging from 0 to last column index.
18+
19+
The recurrence is now kind of obvious.
20+
We can relate minSum[i][j] to minSum[i - 1][j - 1], minSum[i - 1][j] and minSum[i - 1][j + 1],
21+
handling the corner/boundary cases and implementing it in a space efficient way, since
22+
at any point of time we require no longer than 2 row values.
23+

0 commit comments

Comments
 (0)