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?
Input: m = 3, n = 7
Output: 28
Input: m = 3, n = 2
Output: 3
Input: m = 3, n = 3
Output: 6
我的题解:
class Solution {
public:
int uniquePaths(int width_, int height_) {
if (1 == width_ || 1 == height_) return 1;
vector<int> top_list(width_, 1);
vector<int> bottom_list(width_);
for (int NO = 1; NO < height_; NO++)
{
bottom_list[0] = top_list[0];
for (int it = 1; it < width_; it++)
{
bottom_list[it] = bottom_list[it - 1] + top_list[it];
}
top_list = bottom_list;
}
return top_list[width_ - 1];
}
};
假如我没有学过动态规划,这道题我肯定不会用常规编程思想来写,反而很有可能想到 “杨辉三角” 😋
我在学习动态规划的时候见过更 BT 的问题,eg:这些方格中有些为路障,roboot 不能进入,并找到到达终点的最短路径。。
这一对比,果然是新手村的史莱姆 😉
在思考这道题的时候,虽然我第一反应应该需要使用动态,但在实操的时候,也是需要先分析问题的。
分析:
M x N 的表格,从左上到达右下,有多少种走法??
emmm,按照动态规划的思想,大问题的求解可以由小问题的求解推导得出。OK,咱来试试。
假如 M x N 为 3 x 3:
(有点丑😋)
可以很直观看出:
三角,可以从 11 向右 && 12 向下 到达,
也就是说,我们只要知道到达 11 有多少种方法 && 到达 12 有多少种方法,11 nums + 12 nums = △
同理分析 11 && 12:
11 = 21 nums + 22 nums
12 = 22 nums + 23 nums
21 = 31 nums
22 = 31 nums + 32 nums
23 = 32 nums
31 = O nums
32 = O nums
O = 1
Emmm,分析到这一步了,我怎么觉得这是一条直线呢?那不成我还要按照斜线的方式来计算吗???
不对,是不是还缺了点什么。
仔细观察,会发现,最左边以及最顶层,都是由 O 直线行驶过来,值都为 1 (还是画图比较直观)
除了位于边路的节点,其他的节点都是由自己上面的节点 & 自己左面的节点 的值相加得到!
虽然说,在最前面分析的时候,直观的感觉上,它很想斜边的两个节点相加得来,
但是嘞,从上图可以看出,
假如我要计算 第二行最后一列的那个节点的值,并且我已经知道了最顶端的那一层的所有节点的值。
那我不是直接从第二行第一列,向右一直递推了吗?😁
目标节点 = 左节点 + 上节点
上节点全部已知,左节点如果不知道,完全可以由左左节点推出来啊!
OK,不愧是我,看图果然有一手 😉
按照上面的分析(瞎看)我们需要准备两个数组:top_list && bottom_list
top_list 存储数据已知的那一行的数据,
bottom_list 存储待求数据。
起步时,先把 top_list 全部初始化为 1,
根据 目标节点 = 左节点 + 上节点 的公式,从第二列,递推出 bottom_list 中所有的数据,
然后,bottom_list 赋值给 top_list 循环操作 N - 1 次(N 表示总共 N 行)
代码见上方
========= 假装我是分割线 ==========
还记得我最开始说的那句话吗 😉
如果我没学过动态,我肯定会想到“杨辉三角”。
现在你发现我为什么会这么说了吗,
详细答案见最后一张图,也可以自己把上面那张图继续扩展一下,这样看的会跟清楚一些 😃