[LeetCode] Unique Paths && Unique Paths II && Minimum Path Sum (动态规划之 Matrix DP )
Unique Paths
https://oj.leetcode.com/problems/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.
我的思路
我个人通常喜欢将此类问题,叫做 Matrix DP 问题,这道题很显然需要使用动态规划来做,一般做此类 Matrix DP 问题,通常需要注意以下几点:
state: f[x][y] 表示我从起点走到坐标x,y……
function: 研究最后一步怎么走
intialize: 起点
answer: 终点
先来看 state ,可以这样定义,f[x][y] 表示从起点 (0,0) 出发,到达 (x,y) 的 unique paths 。
再来看看怎么找状态转移方程,不难发现,从起点出发到达点 (x,y) 的 unique paths 实际上等于从起点出发到达该点左边一点(也就是(x,y-1))的 unique paths 加上从起点出发到达该点上面一点(也就是(x-1, y))的 unique paths 后的和。
显然该 f 矩阵的初始化是将最左边的一列和最上面的一行置为 1 ,因为由起点出发无论往下走还是往右走,该列或者该行上的每一点的 unique paths 均为1,注意即使 start 位置等于 finish 位置(也就是只有一个点),其 unique paths 也为1(自己走向自己算 1 )。
下面是我在 LeetCode 上 AC 的代码:
/**
* Zhou J
*/ class Solution
{
public:
int uniquePaths(int m, int n)
{
if (m == 0 || n == 0) {
return 0;
} int sum[m][n]; for (int i = 0; i < m; i++) {
sum[i][0] = 1;
} for (int i = 0; i < n; i++) {
sum[0][i] = 1;
} for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
sum[i][j] = sum[i - 1][j] + sum[i][j - 1];
}
} return sum[m - 1][n - 1];
}
};
如果你们理解了上面这一题,可以接着来看下面的 follow question。
Follow Question
Unique Paths II
https://oj.leetcode.com/problems/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
1and0respectively 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.
下面是我 AC 的代码:
/**
* Zhou J
*/ class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) {
if (obstacleGrid.size() == 0)
{
return 0;
} int numOfRows = obstacleGrid.size();
int numOfCols = obstacleGrid[0].size();
vector<vector<int>> sum(obstacleGrid); // initialize the left column
for (size_t ix = 0; ix != numOfRows; ++ix)
{
if (obstacleGrid[ix][0] == 0)
{
sum[ix][0] = 1;
}
else
{
for (size_t newIx = ix; newIx != numOfRows; ++newIx)
{
sum[newIx][0] = 0;
}
break; } // initialize the top row
for (size_t ix = 0; ix != numOfCols; ++ix)
{
if (obstacleGrid[0][ix] == 0)
{
sum[0][ix] = 1;
}
else
{
for (size_t newIx = ix; newIx != numOfCols; ++newIx)
{
sum[0][newIx] = 0;
}
break;
}
} // switch the state
for (size_t i = 1; i != numOfRows; ++i)
{
for (size_t j = 1; j != numOfCols; ++j)
{
if (obstacleGrid[i][j] == 0)
{
sum[i][j] = sum[i-1][j] + sum[i][j-1];
}
else
{
sum[i][j] = 0;
} }
} // return the answer
return sum[numOfRows - 1][numOfCols - 1];
}
};
这倒题目相对上一题,有这样两个注意点:
1. 在初始化行和列的时候,如果有某一个点为障碍物,那么不仅仅该位置所对应的 sum 将置为0,而是其接下来的每一个位置所对应的 sum 都要置为0,这很好理解,一行或一列都属于直线,其中只要有一个障碍物,那么这一整条线路就废掉了。
2. 状态转移的过程中,如果遇到障碍物,改点应该直接返回 0 。
Minimum Path Sum
我们最后再来看一道 Matrix DP 相关的问题,如下:
Minimum Path Sum
https://oj.leetcode.com/problems/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.
此题,实际上和上面两题属于一个套路,只不过此处的状态矩阵 sum 存放的是最短路径和。从起点出发到达某个位置的最短路径和,一定是从起点出发到达该位置左边或者上面一点的最短路径(两者取较小的)加上该点自身的路径。
state: f[x][y]从起点走到x,y的最短路径
function: f[x][y] = min(f[x-1][y], f[x][y-1]) + cost[x][y]
intialize: f[0][0] = cost[0][0]
f[i][0] = sum(0,0 -> i,0)
f[0][i] = sum(0,0 -> 0,i)
answer: f[n-1][m-1]
下面是 AC 的代码:
/**
* Zhou J
*/
class Solution {
public:
int minPathSum(vector<vector<int> > &grid)
{
if (grid.size() == 0)
{
return 0;
} int numOfRows = grid.size();
int numOfCols = grid[0].size();
vector<vector<int>> sum(grid); sum[0][0] = grid[0][0]; // initialize the left column
for (size_t ix = 1; ix != numOfRows; ++ix)
{
sum[ix][0] = sum[ix - 1][0] + grid[ix][0];
} // initialize the top row
for (size_t ix = 1; ix != numOfCols; ++ix)
{
sum[0][ix] = sum[0][ix - 1] + grid[0][ix];
} // switch the state
for (size_t i = 1; i != numOfRows; ++i)
{
for (size_t j = 1; j != numOfCols; ++j)
{
sum[i][j] = min(sum[i][j - 1], sum[i - 1][j]) + grid[i][j];
}
} // return the minimum path sum
return sum[numOfRows - 1][numOfCols - 1]; }
};
刷题心得
LeetCode 是一个非常好的平台,我们在上面做题时,一定要自己先思考,不要急于去 google 答案,如果你的代码 AC 不过,LeetCode 是会把过不了的 TestCase 显示给你的,根据这些提示,我们一步步修正答案,往往会得到很好的锻炼。
个人以为 Matrix DP 一类的动态规划问题通常是最简单的,对于此类题目,initialize 这一步往往是初始化起点对应的行和列。在之后的文章中,我也会针对北美一些面试题中涉及到的动态规划问题做进一步分析。
笔者目前还在国内读硕士,但是前些阶段和一些目前仍然在国内工作,但是日后想去湾区工作的朋友们交流,有一个问题是如果经常跳槽的话,会不会影响北美的面试?答案是会有影响的。我咨询了一个Facebook 的面试官,他的意思是做 intern 经常换工作是无所谓的,但是 fulltime 经常换的话,影响还是很大的。打个比方来说,intern 就相当于女朋友,这个社会现在还是允许我们经常换女朋友的(是有点贱贱嗒),但是 fulltime 就相当于 wife ,你总不能老离婚吧?!
PS:我是有多想去湾区工作啊,求内推~!!
[LeetCode] Unique Paths && Unique Paths II && Minimum Path Sum (动态规划之 Matrix DP )的更多相关文章
- LeetCode: Unique Paths I & II & Minimum Path Sum
Title: https://leetcode.com/problems/unique-paths/ A robot is located at the top-left corner of a m ...
- 64. Minimum Path Sum 动态规划
description: Given a m x n grid filled with non-negative numbers, find a path from top left to botto ...
- 动态规划小结 - 二维动态规划 - 时间复杂度 O(n*n)的棋盘型,题 [LeetCode] Minimum Path Sum,Unique Paths II,Edit Distance
引言 二维动态规划中最常见的是棋盘型二维动态规划. 即 func(i, j) 往往只和 func(i-1, j-1), func(i-1, j) 以及 func(i, j-1) 有关 这种情况下,时间 ...
- LeetCode之“动态规划”:Minimum Path Sum && Unique Paths && Unique Paths II
之所以将这三道题放在一起,是因为这三道题非常类似. 1. Minimum Path Sum 题目链接 题目要求: Given a m x n grid filled with non-negative ...
- 【leetcode】Minimum Path Sum
Minimum Path Sum Given a m x n grid filled with non-negative numbers, find a path from top left to b ...
- 【LeetCode练习题】Minimum Path Sum
Minimum Path Sum Given a m x n grid filled with non-negative numbers, find a path from top left to b ...
- [Leetcode Week9]Minimum Path Sum
Minimum Path Sum 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/minimum-path-sum/description/ Descr ...
- LeetCode 64. 最小路径和(Minimum Path Sum) 20
64. 最小路径和 64. Minimum Path Sum 题目描述 给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小. 说明: 每次只能向下或 ...
- Leetcode之动态规划(DP)专题-64. 最小路径和(Minimum Path Sum)
Leetcode之动态规划(DP)专题-64. 最小路径和(Minimum Path Sum) 给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小. ...
随机推荐
- Swagger与SpringMVC整合
依赖管理 在整合之前,需要把所有使用到的依赖包全部引入.网上很多文章只是简单告诉读者引入swagger-springmvc-1.0.2.jar包,但是随后你发现这远远不够,还需要很多包,如下所示: ...
- eclipse新建maven项目出现红叉解决办法
新建的maven项目,项目内代码及pom.xml没有任何问题,但项目上就是有红叉,这时点开Markers(Window–>show veiw–>Markers),查看错误的详细信息,信息上 ...
- IE6、IE7、Firefox中margin问题及input解决办法
margin不居中的问题 .div{ margin:10px;/*ff*/ *margin:15px;/*ie7*/ _margin:15px;/*ie6*/ 尺寸会变为正常的两倍,按道理应为5px ...
- time,datetime,时间戳 时间格式转换
总结: time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) datetime.datetime.now().strftime( ...
- iOS - OC - XML 解析 - NSXMLParser
//4.解析数据 //4.1 创建XML解析器:SAX NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data]; //4.2 设置代理 ...
- OC线程操作-GCD介绍
1. GCD介绍 1.11.2 1.3 异步具备开启能力但是不是 一定可以开启 1.4 1.5 67. 8.
- 14-n皇后
/*题目内容: 国际象棋中的皇后可以沿着水平线,垂直线,或者斜线前进,吃掉遇到的所有棋子,如果棋盘上有八个皇后,则这八个皇后如何相安无事的放置在棋盘上,1970年与1971年, E.W.Dijkstr ...
- 从输入url到显示网页发生了什么
原文链接:https://juejin.im/post/5bf23afa6fb9a049be5d1494 在浏览器中输入url到显示网页主要包含两个部分: 网络通信和页面渲染 互联网内各网络设备间的通 ...
- rpmdb open failed的解决办法
错误信息如下: “错误:无法从 /var/lib/rpm 打开软件包数据库 CRITICAL:yum.main: Error: rpmdb open failed” ...
- Codeforces 681C. Heap Operations 优先队列
C. Heap Operations time limit per test:1 second memory limit per test:256 megabytes input:standard i ...