Loading

LeetCode 62. 不同路径题解

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。

例题图

问总共有多少条不同的路径?

初看题,自然而然想到递归解法,每个格子只能往下或者往右移动, 那么我们递归移动,直到到达 (m, n) 是停止即可。

void findPaths(int& total, int px, int py, int m, int n) {
    if (px == m && py == n) {
        ++total;
        return;
    }

    if (px < m)
        findPaths(total, px+1, py, m, n);
    
    if (py < n)
        findPaths(total, px, py+1, m, n);
}

思路没有错,但是这种办法很容易超时,原因就是网格太大时爆栈了。

+-----+---- ... ---+---+
| a+b | b | ... |  | 1 |
+-----+---- ... ---+---+
|  a  |   | ...    | 1 |
+-----+---- ... ---+---+
| ... |   | ...    |...|
+-----+---- ... ---+---+
|  1  |     ...    | 0 |
+-----+---- ... ---+---+

仔细观察网格,如果我们从右下开始往回推导。每一个网格的的路径等于其右边网格和下边网格路径之和。所以这里我们从终点往前倒推即可。

\[sum(x, y) = sum(x+1, y) + sum(x, y+1) \]

这种方法的缺点是我们需要一个 \(O(m \cdot n)\) 大小的空间来存储每个网格到终点的路径数目。

int val[m][n] = {0};

for (int x = m-1; x >= 0; --x) {
    for (int y = n-1; y >= 0; --y) {
        if (x == m-1 || y == n-1) {
            val[x][y] = 1;
        } else {
            val[x][y] = val[x+1][y] + val[x][y+1];
        }
    }
}
posted @ 2020-02-25 21:00  sad1e  阅读(83)  评论(0)    收藏  举报