LeetCode 64. Minimum Path Sum

Leetcode : MinimumPathSum

類型:動態(tài)規(guī)劃

題目

給一個 MxN的數(shù)組矩陣,矩陣上每一個左表代表該點的路徑長度,求從左上角到右下角路徑的最短的和。
舉栗:

Input:
[
  [1,3,1],
  [1,5,1],
  [4,2,1]
]
Output : 7 (因為最短路徑是1-3-1-1-1)


思路

解法可以有兩種,動態(tài)規(guī)劃 和 回溯法。
回溯法在這個問題下時間復(fù)雜度太高,是指數(shù)級。
動態(tài)規(guī)劃的時間復(fù)雜度是 O(MxN) M和N是矩陣的長和寬

解法

動態(tài)規(guī)劃

思路:
令矩陣中[0][0] 到 [x][y] 點的最短路徑為 minPath(x,y)
則可以得到遞推公式:
minPath(x,y) = Math.min(minPath(x-1,y), minPath(x,y-1)) + grid[x][y]

則從(0,0)到矩陣上任意一點的最短路徑都可以求得,最終的minPath(m-1,n-1) 就是我們要求的結(jié)果

leetcode submit beats 99.4% - 5ms
下面上代碼:

public static int minPathSum_DP(int[][] grid) {
        int width = grid[0].length;
        int height = grid.length;
        int[][] minDp = new int[height][width];
        int minUp, minLeft;
        for(int i=0; i<height; i++){
            for(int j=0; j<width; j++){
                if(i==0 && j==0){
                    minDp[i][j] = grid[i][j];
                    continue;
                }else if(i==0){
                    minDp[i][j] = minDp[i][j-1] + grid[i][j];
                    continue;
                }else if(j==0){
                    minDp[i][j] = minDp[i-1][j] + grid[i][j];
                    continue;
                }
                minLeft = minDp[i][j-1];
                minUp = minDp[i-1][j];
                minDp[i][j] = minLeft < minUp ? minLeft + grid[i][j] : minUp + grid[i][j];
            }
        }

        return minDp[height-1][width-1];
    }


回溯法
當(dāng)然另一個思路是使用回溯法,但是回溯法執(zhí)行時間太長,時間復(fù)雜度是指數(shù)級的。不過可以作為練習(xí)回溯法的一個TestCase

回溯法的思路是把解題的方式當(dāng)做對一個樹的深度優(yōu)先遍歷
該問題下可以進(jìn)一步優(yōu)化,在每一次往深了走的時候都校驗一下是否已經(jīng)超過目前已知最短路徑,超過就直接返回,不在計算。

代碼如下:

    static int minPath =0;
    static int width=0;
    static int height=0;
    public static int minPathSum_BC(int[][] grid) {
        width = grid[0].length;
        height = grid.length;
        backTracing(0,0,0,grid);
        return minPath;
    }

    // 回溯法要注意,由于在一個邊到頂以后還要回溯另一個邊
    // 所以數(shù)組的臨界條件不能越界, 也就是如下 w==width-1 && h==height-1
    // 相應(yīng)的,遞歸的臨界條件也應(yīng)該使得下一層不能越界
    static void backTracing(int tmp, int h, int w, int[][] grid){
        tmp += grid[h][w];
        if(minPath !=0 && tmp >= minPath){
            return;
        }

        if(h==height-1 && w==width-1){
            minPath = minPath == 0 ? tmp : (tmp<minPath ? tmp : minPath);
            return;
        }

        if(h < height-1){    // 遞歸下一層不能越界
            backTracing(tmp, h+1, w, grid);
        }
        if(w < width-1){   // 遞歸下一層不能越界
            backTracing(tmp, h, w+1, grid);
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 參見貪心算法——最短路徑Dijkstra算法參見動態(tài)規(guī)劃 目錄 0.最短路徑問題0.1 最短路徑問題描述?0.1....
    王偵閱讀 5,161評論 1 9
  • 回溯算法 回溯法:也稱為試探法,它并不考慮問題規(guī)模的大小,而是從問題的最明顯的最小規(guī)模開始逐步求解出可能的答案,并...
    fredal閱讀 14,015評論 0 89
  • LeetCode 刷題隨手記 - 第一部分 前 256 題(非會員),僅算法題,的吐槽 https://leetc...
    蕾娜漢默閱讀 18,395評論 2 36
  • 目錄 1.問題描述1.1 問題描述1.2 各種方法的總結(jié)?1.2.1 分支限界法的總結(jié)?1.2.2 分支限界法與最...
    王偵閱讀 73,599評論 0 31
  • 課堂小助手 心得:第二課這幾天聽了好多次,早起聽,上班路上聽,辦公休息時也在聽,有同事好奇問我“你在聽什么啊?”我...
    平安王鳳瑞伊簾幽夢閱讀 250評論 0 1

友情鏈接更多精彩內(nèi)容