64最小路徑和

題目描述

給定一個包含非負整數的 m x n 網格,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和爲最小。

說明:每次只能向下或者向右移動一步。

示例:

輸入:

[[1,3,1],

[1,5,1],

[4,2,1]
]

輸出: 7

解釋: 因爲路徑 1→3→1→1→1 的總和最小。

思路分析

主體思路都是,下一個位置值=當前位置值+Math.min(往下,往右),在最下行只能往右,在最右列只能往下。

  • 暴力遞歸,時間通不過…
  • 動規做法。簡單的動規,狀態轉移和base case就是上面說的情況。
  • 因爲從右下角往左上角做,所以可以不用新建數組做備忘錄,直接用原來的數組做備忘庫,減少空間複雜度。(力扣上並沒有,時間還多了2ms,小聲bb)

代碼實現

    /**
     * 暴力遞歸,時間超時
     *
     * @param grid
     * @return
     */
    public int minPathSum(int[][] grid) {
        if (grid == null) {
            return 0;
        }
        int row = grid.length;
        int col = grid[0].length;
        return process(grid, row, 0, col, 0);
    }


    public int process(int[][] grid, int row, int curRow, int col, int curCol) {
        if (curRow == row - 1 && curCol == col - 1) {
            return grid[curRow][curCol];
        }
        if (curRow == row) {
            return Integer.MAX_VALUE;
        }
        if (curCol == col) {
            return Integer.MAX_VALUE;
        }
        return grid[curRow][curCol] + Math.min(process(grid, row, curRow + 1, col, curCol),
                process(grid, row, curRow, col, curCol + 1));
    }

    /**
     * 簡單動規,建立一個備忘錄
     *
     * @param grid
     * @return
     */
    public int minPathSum1(int[][] grid) {
        if (grid == null) {
            return 0;
        }
        int row = grid.length - 1;
        int col = grid[0].length - 1;
        int[][] dp = new int[row + 1][col + 1];
        for (int i = row; i >= 0; i--) {
            for (int j = col; j >= 0; j--) {
                if (i == row && j != col) {
                    dp[i][j] = grid[i][j] + dp[i][j + 1];
                } else if (i != row && j == col) {
                    dp[i][j] = grid[i][j] + dp[i + 1][j];
                } else if (i != row && j != col) {
                    dp[i][j] = grid[i][j] + Math.min(dp[i + 1][j], dp[i][j + 1]);
                } else {
                    dp[i][j] = grid[i][j];
                }
            }
        }
        return dp[0][0];
    }

    /**
     * 用原本的數組作爲備忘錄
     * @param grid
     * @return
     */
    public int minPathSum2(int[][] grid) {
        if (grid == null) {
            return 0;
        }
        for (int i = grid.length - 1; i >= 0; i--) {
            for (int j = grid[0].length - 1; j >= 0; j--) {
                if (i == grid.length - 1 && j != grid[0].length - 1)
                    grid[i][j] = grid[i][j] + grid[i][j + 1];
                else if (j == grid[0].length - 1 && i != grid.length - 1)
                    grid[i][j] = grid[i][j] + grid[i + 1][j];
                else if (j != grid[0].length - 1 && i != grid.length - 1)
                    grid[i][j] = grid[i][j] + Math.min(grid[i + 1][j], grid[i][j + 1]);
            }
        }
        return grid[0][0];
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章