• LeetCode之“动态规划”:Minimum Path Sum && Unique Paths && Unique Paths II


      之所以将这三道题放在一起,是因为这三道题非常类似。

      1. 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.

      该题解答参考自一博文

      设dp[i][j]表示从左上角到grid[i][j]的最小路径和。那么dp[i][j] = grid[i][j] + min( dp[i-1][j], dp[i][j-1] );

      下面的代码中,为了处理计算第一行和第一列的边界条件,我们令dp[i][j]表示从左上角到grid[i-1][j-1]的最小路径和,最后dp[rows][cols]是我们所求的结果

     1 int minPathSum(vector<vector<int>>& grid) {
     2     int rows = grid.size();
     3     if(rows == 0)
     4         return 0;
     5     int cols = grid[0].size();
     6     
     7     vector<vector<int> > dp(rows + 1, vector<int>(cols + 1, INT_MAX));
     8     dp[0][1] = 0;
     9     for(int i = 1; i < rows + 1; i++)
    10         for(int j = 1; j < cols + 1; j++)
    11             dp[i][j] = grid[i - 1][j - 1] + min(dp[i][j - 1], dp[i - 1][j]);
    12     
    13     return dp[rows][cols];
    14 }
    View Code 

      注意到上面的代码中dp[i][j] 只和上一行的dp[i-1][j]和上一列的dp[i][j-1]有关,因此可以优化空间为O(n)(准确来讲空间复杂度可以是O(min(row,col)))

     1 int minPathSum(vector<vector<int>>& grid) {
     2     int rows = grid.size();
     3     if(rows == 0)
     4         return 0;
     5     int cols = grid[0].size();
     6 
     7     vector<int> dp(cols + 1, INT_MAX);
     8     dp[1] = 0;
     9     for(int i = 1; i < rows + 1; i++)
    10         for(int j = 1; j < cols + 1; j++)
    11             dp[j] = grid[i-1][j-1] + min(dp[j-1], dp[j]);
    12     
    13     return dp[cols];
    14 }
    View Code

      2. Unique Paths

        题目链接

      题目要求:

      A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).

      The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

      How many possible unique paths are there?

      

      Above is a 3 x 7 grid. How many possible unique paths are there?

      Note: m and n will be at most 100.

      这道题的解答跟上一道题是非常类似的,程序如下:

     1 int uniquePaths(int m, int n) {
     2     if(m == 0 && n == 0)
     3         return 0;
     4     
     5     vector<vector<int> > dp(m, vector<int>(n, 1));
     6     for(int i = 1; i < m; i++)
     7         for(int j = 1; j < n; j++)
     8             dp[i][j] = dp[i-1][j] + dp[i][j-1];
     9     
    10     return dp[m-1][n-1];
    11 }
    View Code

      优化空间程序:

     1 int uniquePaths(int m, int n) {
     2     if(m == 0 && n == 0)
     3         return 0;
     4 
     5     vector<int> dp(n, 1);
     6     for(int i = 1; i < m; i++)
     7         for(int j = 1; j < n; j++)
     8             dp[j] = dp[j-1] + dp[j];
     9     
    10     return dp[n - 1];
    11 }
    View Code

      3. Unique Paths II

      题目链接

      题目要求:

      Follow up for "Unique Paths":

      Now consider if some obstacles are added to the grids. How many unique paths would there be?

      An obstacle and empty space is marked as 1 and 0 respectively in the grid.

      For example,

      There is one obstacle in the middle of a 3x3 grid as illustrated below.

    [
      [0,0,0],
      [0,1,0],
      [0,0,0]
    ] 

      The total number of unique paths is 2.

      Note: m and n will be at most 100.

      这道题跟上一道题基本一致,不同的地方在于我们需要将能到达存在obstacle的地方的路径数置为0。程序如下:

     1 int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
     2     int rows = obstacleGrid.size();
     3     if(rows == 0)
     4         return 0;
     5         
     6     int cols = obstacleGrid[0].size();
     7     if(cols == 0)
     8         return 0;
     9         
    10     vector<vector<int> > dp(rows, vector<int>(cols, 1));
    11     int i = 0;
    12     while(i < rows)
    13     {
    14         if(obstacleGrid[i][0] == 1)
    15             while(i < rows)
    16             {
    17                 dp[i][0] = 0;
    18                 i++;   
    19             }
    20         i++;
    21     }
    22     int j = 0;
    23     while(j < cols)
    24     {
    25         if(obstacleGrid[0][j] == 1)
    26             while(j < cols)
    27             {
    28                 dp[0][j] = 0;
    29                 j++;   
    30             }
    31         j++;
    32     }
    33     
    34     for(i = 1; i < rows; i++)
    35         for(j = 1; j < cols; j++)
    36         {
    37             if(obstacleGrid[i][j] == 1)
    38                 dp[i][j] = 0;
    39             else
    40                 dp[i][j] = dp[i-1][j] + dp[i][j-1];
    41         }
    42 
    43     return dp[rows-1][cols-1];
    44 }
    View Code
  • 相关阅读:
    UI涂鸦板设计代码
    UI简单计算器设计代码
    用户需求、己、竞争对手的关系
    总结一下,以软件开发生命周期来说明不同的测试的使用情况
    谈软件工程和计算机科学的区别
    有人认为,”中文编程“是解决中国程序员编程效率的秘密武器,请问它是一个“银弹”吗?
    安装Eclipse SVN插件
    UI中横屏竖屏切换的一些方法(转)
    Object-C总结
    js备忘录
  • 原文地址:https://www.cnblogs.com/xiehongfeng100/p/4573631.html
Copyright © 2020-2023  润新知