JavaScript|LeetCode|动态规划|64.最小路径和

法1:动态规划(未优化版)
想法:

  1. 对于第 i 行、第 j 列位置,从左上角到此位置的最小路径为:
    dp[i][j] = grid[i][j] + min{dp[i - 1][j] , dp[i][j - 1]}
    dp[i - 1][j] 表示从上走到下到达[i][j];dp[i][j - 1]表示从左走到右到达[i][j]
/** 
* @param {number[][]} grid
* @return {number} 
*/
var minPathSum = function(grid) {    
    var dp = [], temp = [];    
    var i = 0, j = 0, m = grid.length, n = grid[0].length;    
    for(i = 0; i < m; i++) {        
        for(j = 0; j < n; j++) {            
            temp[j] = 0;        
        }        
        dp[i] = temp;        
        temp = [];    
    }    
    for(i = 0; i < m; i++) {        
        for(j = 0; j < n; j++) {            
            if(i - 1 >= 0 && j - 1 >= 0) {                
                dp[i][j] = grid[i][j] + Math.min(dp[i - 1][j], dp[i][j - 1]);                
                continue;            
            }            
            if(i - 1 >= 0 && j - 1 < 0) {                
                dp[i][j] = grid[i][j] + dp[i - 1][j];                
                continue;            
            }            
            if(i - 1 < 0 && j - 1 >= 0) {                
                dp[i][j] = grid[i][j] + dp[i][j - 1];                
                continue;            
            }            
            dp[i][j] = grid[i][j];        
        }    
    }    
    return dp[m - 1][n - 1];
};

法2:动态规划(优化)
看了题解,参考做了一些优化。
想法:

  1. 右下角的列坐标必定等于grid的最大列坐标
  2. 行坐标作为外循环,列坐标作为内循环;则经过一轮内循环后,列坐标与右下角列坐标相等,若此时行坐标与右下角行坐标相等,则自动退出循环
  3. 则:实际上只需要一个一维数组,来保存每行的最短路径情况。即dp[],长度为grid[0].length。假设已经访问了第一行,访问到第二行时,如第j位置时,可选择min{dp[j - 1], dp[j]};此时dp[j - 1]是已经更新的到达第2行第j - 1列的最短路径(当前要达到位置的左方),dp[j]是尚未更新的到达第1行第j列的最短路径(当前要到达位置的上方)。这样dp中保存的是:左上角到达最新一行中每个位置的最短路径。
/** 
* @param {number[][]} grid 
* @return {number} 
*/
var minPathSum = function(grid) {    
    var dp = [];    
    var i = 0, j = 0, m = grid.length, n = grid[0].length;    
    for(j = 0; j < n; j++) {        
        dp[j] = 0;    
    }    
    for(i = 0; i < m; i++) {        
        for(j = 0; j < n; j++) {            
            if(j == 0) { // 在第一列,只能从上边来                
                dp[j] = dp[j];            
            }            
            else if(i == 0) { // 在第一行,只能从左边来                
                dp[j] = dp[j - 1];            
            }            
            else {                
                dp[j] = Math.min(dp[j - 1], dp[j]);            
            }            
            dp[j] = dp[j] + grid[i][j];        
        }    
    }    
    return dp[n - 1];
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值