1. // 暴力递归方式:
    2. public static int minPathSum(int[][] m) {
    3. if (m == null || m.length == 0 || m[0] == null || m[0].length == 0) {
    4. return 0;
    5. }
    6. return process(m, 0, 0);
    7. }
    8. public static int process(int[][] arr, int x, int y) {
    9. if (x == arr.length - 1 && y == arr[0].length - 1) {
    10. return arr[x][y];
    11. }
    12. // if (x > arr.length - 1 || y > arr[0].length - 1){
    13. // return 0;
    14. // }
    15. int p1 = x + 1 < arr.length ? (arr[x][y] + process(arr, x + 1, y)) : Integer.MAX_VALUE;
    16. int p2 = y + 1 < arr[0].length ? (arr[x][y] + process(arr, x, y + 1)) : Integer.MAX_VALUE;
    17. return Math.min(p1, p2);
    18. }
    19. public static int minPathSum1(int[][] m) {
    20. if (m == null || m.length == 0 || m[0] == null || m[0].length == 0) {
    21. return 0;
    22. }
    23. int row = m.length;
    24. int col = m[0].length;
    25. int[][] dp = new int[row][col];
    26. dp[0][0] = m[0][0];
    27. for (int i = 1; i < row; i++) {
    28. dp[i][0] = dp[i - 1][0] + m[i][0];
    29. }
    30. for (int j = 1; j < col; j++) {
    31. dp[0][j] = dp[0][j - 1] + m[0][j];
    32. }
    33. for (int i = 1; i < row; i++) {
    34. for (int j = 1; j < col; j++) {
    35. dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + m[i][j];
    36. }
    37. }
    38. return dp[row - 1][col - 1];
    39. }
    40. // 空间压缩技巧,将dp[row][col] 压缩为 dp[col]
    41. public static int minPathSum2(int[][] m) {
    42. if (m == null || m.length == 0 || m[0] == null || m[0].length == 0) {
    43. return 0;
    44. }
    45. int row = m.length;
    46. int col = m[0].length;
    47. int[] dp = new int[col];
    48. dp[0] = m[0][0];
    49. for (int j = 1; j < col; j++) {
    50. dp[j] = dp[j - 1] + m[0][j];
    51. }
    52. for (int i = 1; i < row; i++) {
    53. dp[0] += m[i][0];
    54. for (int j = 1; j < col; j++) {
    55. dp[j] = Math.min(dp[j - 1], dp[j]) + m[i][j];
    56. }
    57. }
    58. return dp[col - 1];
    59. }
    60. // for test
    61. public static int[][] generateRandomMatrix(int rowSize, int colSize) {
    62. if (rowSize < 0 || colSize < 0) {
    63. return null;
    64. }
    65. int[][] result = new int[rowSize][colSize];
    66. for (int i = 0; i != result.length; i++) {
    67. for (int j = 0; j != result[0].length; j++) {
    68. result[i][j] = (int) (Math.random() * 100);
    69. }
    70. }
    71. return result;
    72. }
    73. // for test
    74. public static void printMatrix(int[][] matrix) {
    75. for (int i = 0; i != matrix.length; i++) {
    76. for (int j = 0; j != matrix[0].length; j++) {
    77. System.out.print(matrix[i][j] + " ");
    78. }
    79. System.out.println();
    80. }
    81. }
    82. public static void main(String[] args) {
    83. int rowSize = 10;
    84. int colSize = 10;
    85. int[][] m = generateRandomMatrix(rowSize, colSize);
    86. System.out.println(minPathSum(m));
    87. System.out.println(minPathSum1(m));
    88. System.out.println(minPathSum2(m));
    89. }
    // 动态规划 
    public int minPathSum(int[][] grid) {
        if (grid == null || grid.length == 0) {
            return 0;
        }
    
        int M = grid.length;
        int N = grid[0].length;
    
        int[][] dp = new int[M][N];
        dp[M - 1][N - 1] = grid[M - 1][N - 1];
        // 最后一行
        for (int i = N - 2; i >= 0; i--) {
            dp[M - 1][i] = grid[M - 1][i] + dp[M - 1][i + 1];
        }
        // 最后一列
        for (int i = M - 2; i >= 0; i--) {
            dp[i][N - 1] = grid[i][N - 1] + dp[i + 1][N - 1];
        }
        //中间  从底向上 从右向左依次赋值
        for (int i = M - 2; i >= 0; i--) {
            for (int j = N - 2; j >= 0; j--) {
                dp[i][j] = grid[i][j]+Math.min(dp[i+1][j],dp[i][j+1]);
            }
        }
        return dp[0][0];
    }