• (LeetCode 64)Minimum Path Sum


    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.

    题目:

    在一个m行n列的二维数组中,每个元素都是非负数,从左上角走到右下角,每次只能向右或向下走,求该路径的总和最小。

    思路:

    1、枚举

    枚举所有路径,从左上角到右下角,共经过m+n-2步,其中向下走m-1步,向右走n-1步,因此所有可能路径数为C(m+n-2,m-1),算出所有路径的总和,找出最小的。

    暴力枚举是万能的,但是不实际。

    2、动态规划

    假设dp[i][j]表示从左上角走到(i,j)的路径最小总和,因为每一步只能往下或往右,因此可以从左边(i-1,j)或上边(i,j-1)走到(i,j)。

    状态转移方程:

    dp[i][j]=min(dp[i-1][j],dp[i][j-1])+A[i][j]

    初始值:

    dp[0][0]=A[0][0],

    dp[i][0]=dp[i-1][0]+A[i][0],

    dp[0][j]=dp[0][j-1]+A[0][j].

    复杂度:

    时间复杂度O(m*n),空间复杂度O(m*n)

    空间优化:

    dp[i][j]=min(dp[i-1][j],dp[i][j-1]),只与dp[i-1][j],dp[i][j-1]有关,可以去掉一维,只剩下

    dp[j]=min(dp[j],dp[j-1]),因为等号右边的dp[j]是旧的,即dp[i-1][j],等号右边的dp[j-1]是新的,即dp[i][j-1](从循环i,j中可以明显看出来)

    代码:

    class Solution {
    public:
        int minPathSum(vector<vector<int>>& grid) {
            int m=grid.size();
            int n=grid[0].size();
            vector<vector<int> > dp(m,vector<int>(n,0));
    
            for(int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    if(i==0){
                        if(j==0)
                            dp[i][j]=grid[i][j];
                        else
                            dp[i][j]=dp[i][j-1]+grid[i][j];
                    }
                    else if(j==0)
                        dp[i][j]=dp[i-1][j]+grid[i][j];
                    else
                        dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i][j];
                }
            }
            return dp[m-1][n-1];
        }
    };
    
    class Solution {
    public:
        int minPathSum(vector<vector<int>>& grid) {
            int m=grid.size();
            int n=grid[0].size();
            vector<int> dp(n,0);
    
            for(int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    if(i==0){
                        if(j==0)
                            dp[j]=grid[i][j];
                        else
                            dp[j]=dp[j-1]+grid[i][j];
                    }
                    else if(j==0)
                        dp[j]=dp[j]+grid[i][j];
                    else
                        dp[j]=min(dp[j],dp[j-1])+grid[i][j];
                }
            }
            return dp[n-1];
        }
    };
  • 相关阅读:
    python线程的几种创建方式
    python进程之间的通信——Queue
    python中进程的几种创建方式
    python中的生成器、迭代器、闭包、装饰器
    java中String和StringBuffer的区别
    python中的元类介绍
    宣传片制作技巧
    树莓派创建WiFi热点
    PCB布线要求
    jsoncpp linux平台编译和arm移植
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4601576.html
Copyright © 2020-2023  润新知