zoukankan      html  css  js  c++  java
  • 【Leetcode】【Medium】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:

    一上去就觉得是简单题:

    如果当前格位于第m行或第n列,则只有一种路径;

    否则当前格路径数等于“右格路径数”+“下格路径数”;

    代码(未AC):

    1 class Solution {
    2 public:
    3     int uniquePaths(int m, int n) {
    4         if (m == 1 || n == 1)
    5             return 1;
    6         
    7         return uniquePaths(m - 1, n) + uniquePaths(m, n - 1);
    8     }
    9 };

    结果提示超时了。

    思路2:

    考虑超时原因很可能是使用了函数递归,为避免使用递归,新建一个m*n的矩阵空间用于保存每个点计算的路径数。用新建空间保存结果,代替递归。

    代码(AC):

     1 class Solution {
     2 public:
     3     int uniquePaths(int m, int n) {
     4         vector<vector<int> > grid(m, vector<int>(n, 1));
     5         for (int i = 1; i < m; ++i) {
     6             for (int j = 1; j < n; ++j) {
     7                 grid[i][j] = grid[i-1][j] + grid[i][j-1];
     8             }
     9         }
    10         
    11         return grid[m-1][n-1];
    12     }
    13 };

    思路3:

    上述代码时间复杂度o(m*n),空间复杂度o(m*n),通过观察路径数量规律,还可以减少空间复杂度为o(n)。

    已知grid[i][j] = grid[i-1][j] + grid[i][j-1];

    进一步将后一项grid[i][j-1]替换为grid[i-1][j-1] + grid[i][j-2];

    不断查分后一项,最终grid[i][j] = grid[i-1][j] + grid[i-1][j-1] + grid[i-1][j-2] + ... + grid[i-1][1] + grid[i][0];

    又因为grid[i][0] = grid[i-1][0] = 1;

    所以grid[i][j] 就等于第i-1行,从0到j所有元素之和;

    得到了这个规律,我们只需要一个长度为n的数组col,通过第0行计算第1行,并不断迭代,最终得到第m行格子存在的路径数,此时col[n-1]即为所求.

     1 class Solution {
     2 public:
     3     int uniquePaths(int m, int n) {
     4         vector<int> col(n, 1);
     5         for (int i = 1; i < m; ++i) {
     6             for (int j = 1; j < n; ++j) {
     7                 col[j] = col[j-1] + col[j];
     8             }
     9         }
    10         
    11         return col[n-1];
    12     }
    13 };

    思路4:

    可以通过分析排列组合暴力求解:

    从格子起始,一共需要移动n+m-2步,可以到达终点。

    这n+m-2步中,有m-1步需要向下移动。

    问题转化为,从n+m-2步中,选择m-1步向下移动,有多少种选择方法。

    因此通过计算Combination(n+m-2, m-1)即可求得答案.

    代码(超时):

     1 class Solution {
     2 public:
     3     int uniquePaths(int m, int n) {
     4         long long dividend = 1;
     5         long long divisor = 1;
     6         for (int i = 1; i <= m - 1; ++i) {
     7             dividend *= i + n - 1;
     8             divisor *= i;
     9         }
    10             
    11         return int(dividend / divisor);
    12     }
    13 };

    代码超时,未AC,正要放弃,看了讨论区的代码..原来用浮点数直接除,结果是正确的;

    即(代码AC):

     1 class Solution {
     2 public:
     3     int uniquePaths(int m, int n) {
     4         double res = 1;
     5         for (int i = 1; i <= m - 1; ++i) {
     6             res = res * (i + n - 1) / i;
     7         }
     8             
     9         return int(res);
    10     }
    11 };
  • 相关阅读:
    2020年北航OO助教工作总结
    OO第四单元——UML及其解析器——总结 暨 OO课程大总结
    OO第三单元——规格化设计与地铁系统——总结
    OO第二单元——电梯调度——总结
    OO第一单元——表达式求导——总结
    try_svg
    字体自适应
    网站使用微软雅黑需要版权吗
    body,td,th {
    input一定要在from里吗
  • 原文地址:https://www.cnblogs.com/huxiao-tee/p/4467828.html
Copyright © 2011-2022 走看看