经常遇到给定的m×n中求左上角开始起步,到达右下角的问题。这类问题可以统一用辅助数组,利用dp来解决。
62. 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?
题目解析:
代码如下:
class Solution {
public:
// 使用动态规划解题,能够到达每个格子,只能是从他的上方或者左侧到达
int uniquePaths(int m, int n)
{
// 建立dp
vector<vector<int>>dp(m, vector<int>(n, 0));
// 填充第一行
for(int j=0; j<n; ++j)
dp[0][j] = 1;
// 填充第一列
for(int i=0; i<m; ++i)
dp[i][0] = 1;
// 填充剩余空间
for(int i=1; i<m; ++i)
{
for(int j=1; j<n; ++j)
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
return dp[m-1][n-1];
}
};
63. Unique Paths II
题目描述:
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.
题目解析:
代码如下:
class Solution {
public:
// 使用动态规划解题
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid)
{
int m = obstacleGrid.size();
int n = obstacleGrid[0].size();
// 建立dp
vector<vector<int>>dp(m, vector<int>(n, 0));
// 填充第一行
for(int j=0; j<n; ++j)
{
if(obstacleGrid[0][j])
break;
dp[0][j] = 1;
}
// 填充第一列
for(int i=0; i<m; ++i)
{
if(obstacleGrid[i][0])
break;
dp[i][0] = 1;
}
// 填充剩余空间
for(int i=1; i<m; ++i)
{
for(int j=1; j<n; ++j)
{
if(obstacleGrid[i][j])
continue;
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1];
}
};
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.
Example 1:
[[1,3,1], [1,5,1], [4,2,1]]Given the above grid map, return
7
. Because the path 1→3→1→1→1 minimizes the sum.
题目解析:
1. 此题题意是求:在m×n的方格中,从左上角到达右下角的最小花费或者最小和。没经过一个格子,就必须付出这个格子所代表的花费。
2. 依然采用dp来解决此问题。dp[i][j] = dp[i-1][j] < dp[i][j-1] ? dp[i-1][j] :dp[i][j-1],因为到一个格子的上一步只能是当前格子的上方或者当前格子的下方。这样每次到一个格子都求的是到当前格子的最小花费。累计到右下角的格子,就是到右下角的最小花费。
代码如下:
class Solution {
public:
// 使用动态规划,简便易懂
int minPathSum(vector<vector<int>>& grid)
{
int m = grid.size();
int n = grid[0].size();
//创建dp
vector<vector<int>>dp(m, vector<int>(n, 0));
// 初始化第一行
dp[0][0] = grid[0][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)
dp[i][0] = dp[i-1][0] + grid[i][0];
// 填充辅助数组
for(int i=1; i<m; ++i)
{
for(int j=1; j<n; ++j)
{
dp[i][j] = dp[i-1][j] < dp[i][j-1] ? dp[i-1][j] : dp[i][j-1];
dp[i][j] += grid[i][j];
}
}
return dp[m-1][n-1];
}
};