LeetCode Minimum Path Sum

来源:互联网 发布:linux终端连接redis 编辑:程序博客网 时间:2024/06/11 04:14

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.

Note: You can only move either down or right at any point in time.

思路分析:这题是MSRA面试遇到过的原题,可见IT公司面试刷题太重要太重要。如果做过类似的dp题目就会觉得这题非常简单,几乎可以5分钟秒掉。这题和Unique Paths Unique Paths II 是同类型的题目,类似的dp套路,由于每个格子的入口只有左边相邻和上边相邻的格子,定义数组dp[m][n]令dp[i][j]表示从起点到(i,j)的最短路径和(稍微变形也可以改成最大路径和),容易得到dp递推式 dp[i][j] = grid[i][j] + min{dp[i-1][j], dp[i][j-1]},有了递推式,实现就非常容易了,就是不断填二维数组,两个for循环搞定。但是这题空间上还可以进一步优化,因为只需要使用相邻上一行dp数组的信息,也可以定义一维数组dp来做,严谨的做法是如果是m行n列,就取m n中较小的定义dp数组。这里给出的实现是O(n)空间的解法,定义一维dp数组保存相邻上一行信息递归计算。

AC Code

使用O(m*n)空间的版本

public int minPathSum(int[][] grid) {        //0911        int m = grid.length;        if(m == 0) return 0;        int n =  grid[0].length;        int [][] dp = new int [m][n];        dp[0][0] = grid[0][0];        for(int i = 1; i < m; i++){            dp[i][0] = dp[i-1][0] + grid[i][0];        }        for(int j = 1; j < n; j++){            dp[0][j] = dp[0][j-1] + grid[0][j];        }        for(int i = 1; i < m; i++){            for(int j = 1; j < n; j++){                dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1]) + grid[i][j];            }        }        return dp[m-1][n-1];    }
使用O(n)空间的版本,还可以进一步优化,取m和n中较小的一个定义dp数组,空间复杂度为O(min(m,n))

public int minPathSum(int[][] grid) {        //0932        int m = grid.length;        if(m == 0) return 0;        int n = grid[0].length;        int [] dp = new int[n];        dp[0] = grid[0][0];        for(int j = 1; j < n; j++){            dp[j] = dp[j-1] + grid[0][j];        }        for(int i = 1; i < m; i++){            for(int j = 0; j < n; j++){                if(j == 0){                    dp[j] += grid[i][j];                } else {                    dp[j] = grid[i][j] + Math.min(dp[j], dp[j-1]);                }            }        }        return dp[n-1];        //0942    }



0 0
原创粉丝点击