931. Minimum Falling Path Sum

DFS + memo

T: O(3^row)

S: O(row*col)

public class Solution {
    public int minFallingPathSum(int[][] matrix) {
        int m = matrix.length;
        int n = matrix[0].length;        
        Integer[][] memo = new Integer[m][n];
        
        int min = Integer.MAX_VALUE;
        // ๅพž row 0 ้–‹ๅง‹่ท‘ๆ‰€ๆœ‰ row 0 ็š„ cell, ไพ†ๅšไน‹ๅพŒ็š„ๅˆ†ๆ”ฏ
        // ๆ‰€ไปฅๆŠŠ 0,0  0,1  0,2 ไธŸๅ…ฅ dfs function
        for (int c = 0; c < n; c++) { // row 0, put all (row, col)
            // ๅ› ็‚บๆœ‰ๅš memo, ๆ‰€ไปฅ 0,1  0,2 ่ท‘็š„ๆ™‚ๅ€™, ๅ…ถๅฏฆไธ‹้ข dfs ็š„ๅˆ†ๆ”ฏ้ƒฝ่จˆ็ฎ—้Žไบ†
            min = Math.min(min, dfs(matrix, 0, c, memo));
        }
        return min;
    }
    // dfs function ไพ† recursive ่จˆ็ฎ— min path value
    private int dfs(int[][] matrix, int row, int col, Integer[][] memo) {
        int m = matrix.length;
        int n = matrix[0].length;
        if (!isValid(m, n, row, col)) {
            return 0;
        }
        if (memo[row][col] != null) {
            return memo[row][col];
        }

        int min = Integer.MAX_VALUE;
        
        for (int i = -1; i <= 1; i++) {
            if (!isValid(m, n, row, col+i)) { // why check row..., not row+1 ?
                // because row+1 check is in the beginning of dfs? so why need check?
                continue;
            }
            // for every cell (row, col) 
            // => has 3 branch => (row+1, col-1),(row+1, col), (row+1, col-1)
            // sum = ็›ฎๅ‰ๅ€ผ + 3 ๅˆ†ๆ”ฏ็š„ๅ€ผ
            int sum = matrix[row][col] + dfs(matrix, row+1, col + i, memo);
            min = Math.min(min, sum); // ๅ–ๆœ€ๅฐ็š„
            
        }
        memo[row][col] = min; // ็ด€้Œ„ๆœ€ๅฐๅ€ผ
        return min;
    }
    private boolean isValid(int m, int n, int row, int col) {
        return row >= 0 && row < m && col >=0 && col < n;
    }
}

/*

row.  [0,0  0,1  0,2]  
      /|\
r+1,c-1 c c+1 


T: O(3^row)
S: O(mn)

*/

DP

top down, because this Q ask from top to end's min path sum

T: O(mn)
S: O(mn)
class Solution {
    public int minFallingPathSum(int[][] matrix) {
        int m = matrix.length;
        int n = matrix[0].length;
        
        int[][] dp = new int[m][n];
        for (int j = 0; j < n; j++) {
            dp[0][j] = matrix[0][j];
        }
        for (int i = 1; i < m; i++) {
            for (int j = 0; j < n; j++) {
                
                dp[i][j] = dp[i-1][j];
                if (j-1 >= 0) {
                    dp[i][j] = Math.min(dp[i][j], dp[i-1][j-1]);
                }
                if (j+1 < n) {
                    dp[i][j] = Math.min(dp[i][j], dp[i-1][j+1]);
                }
                dp[i][j] += matrix[i][j];
            }
        }
        int res = Integer.MAX_VALUE;
        for (int j = 0; j < n; j++) {
            res = Math.min(res, dp[m-1][j]);
        }
        return res;
    }
}

/*
so from questions:

dp[i][j]: the minimum sum of any falling path through matrix, from 0 to m-1 rows.

dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i-1][j+1]) + A[i][j]

at last row find the min(dp[m-1][j]), is the ans

T: O(mn)
S: O(mn)
*/

Last updated