9.最小路径和

给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:每次只能向下或者向右移动一步。

示例:

输入:
[
  [1,3,1],
  [1,5,1],
  [4,2,1]
]
输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。

思路:

要想知道最小路径,不把网格所有点都走一次是不可能知道的,单凭是右点大数值还是下点数值大选择移动路径是不对的,你永远不知道再前方会发生什么,不然示例路径第二步应该往下(1)而不是往右(3)走了。

但是都用搜索的方法把从起点到终点的路径都走一遍,那效率也太低了,要是地图再大一点,这么多条路,鬼知道什么时候能走完!

但是,无论经过一个网格点的路有多少条,只有一条路是最优,那我们还费什么劲,做无用功去搜索那些不是最优解的路呢?

将来总最优路径一定是从各个网格点最优路径里面选出来的。网格点m*n个,路径也就m*n条,比起搜索的路径不知道少到哪里去了。

求一条最优路径就够呛了,现在还要求m*n条最优路径,那怎么求啊?

由于只能往下和右走,对于某个网格,有两条分别从左和上来的路径要经过这个它(这两条路径都是到左点和上点的最优路径)

                  最优路径1                                                              到该网格最小路径不言而喻,自然 min(路径1,路径2)+ 网格值

最优路径2    网格                                                                    

那么怎么求路径1和路径2呢?把该网格的左和上像上面一样分析就行了啊

设dp[m][n]为起点到点(m,n)的最优路径,array[m][n]为点(m,n)的值

通过这波递归分析,可以得到:dp[m][n] = min ( dp[m-1][n] , dp[m][n-1]) + array[m][n]

为了节约空间,直接用array数组当做dp数组,用来存储最优路径

当然,对于上边界和左边界来说,到那些点的走法单一,没得选。

1 3 1         起点到每个点的最小路径和:           1 4 5

1 5 1                                                                        2 7 6

4 2 1                                                                        6 8 7

/*       上路径
           ↓
左路径  → 某点
 
当然 如果某点在列1,只有上到下
        某点在排1,只有左到右
*/
class Solution {
    public int minPathSum(int[][] grid) {
        int m=grid.length,n=grid[0].length;
        int dp[][]=new int[m][n];
        dp[0][0]=grid[0][0];
        for(int i=0;i<m;++i){
            for(int j=0;j<n;++j){
                if(j==0 && i>0){
                    dp[i][j]=grid[i][j]+dp[i-1][j];
                }
                if(i==0 && j>0){
                    dp[i][j]=grid[i][j]+dp[i][j-1];
                }
                if(i>0 && j>0){
                    dp[i][j]=Math.min(dp[i-1][j],dp[i][j-1])+grid[i][j];
                }
            }
        }
        return dp[m-1][n-1];
    }
}

猜你喜欢

转载自blog.csdn.net/qq_40636117/article/details/82875266
今日推荐