zoukankan      html  css  js  c++  java
  • [LeetCode]19. 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-1步,向右移动n-1步。每次移动前,判断是否还能向下或者向右移动。在向下或者向右移动一步后,接下来的移动过程可以递归调用。

    class Solution {
    public:
        int uniquePaths(int m, int n) {
            int i = m, j = n;
            int res = 0;
            if (i <= 1 || j <= 1)
            {
                res += 1;
                return res;
            }
            else if (i > 1 && j > 1)
                res += uniquePaths(i - 1, j) + uniquePaths(i, j - 1);
            else if (i > 1 && j <= 1)
                res += uniquePaths(i - 1, j);
            else if (i <= 1 && j > 1)
                res += uniquePaths(i, j - 1);
        }
    };

    换个思路考虑,如果某次移动到了最下行或者最右行,则接下来的移动没有选择,只有一条路径了。因此可以改进程序如下所示:

    class Solution {
    public:
        int uniquePaths(int m, int n) {
            if(m == 1 || n == 1)
                return 1;
            else
                return uniquePaths(m - 1, n) + uniquePaths(m, n - 1);
        }
    };

    因为递归调用,在m,n较大时会出现Time Limit Exceeded

    解法2:从左上角走到右下角需要向下移动m-1步,向右移动n-1步,一共移动m+n-2步。因为中间没有任何障碍,所以很简单:即是在m+n-2步中取m-1步向下,或者是在m+n-2步中取n-1步向右即可。即是求组合数C(m+n-2,m-1)或者C(m+n-2,n-1)。因为m+n-2=m-1+n-1,假设n>m,则C(m+n-2,m-1)=(m+n-2)*(m+n-3)*...*n/(m-1)!。

    class Solution {
    public:
        int uniquePaths(int m, int n) {
            int res = 0;
            int a = m > n ? m : n;
            int b = m + n - a - 1;
            int sum = m + n - 2;
            long long p1 = 1, p2 = 1;
    
            while (sum >= a)
                p1 =  p1 * sum--;
            while (b >= 1)
                p2 = p2 * b--;
            res = p1 / p2;
            return res;
        }
    };

    解法3:动态规划。移动到[i,j]的路径path[i,j]=path[i-1,j]+path[i,j-1](0<i<m,0<j<n),初始化path[i][0]=1,path[0][j]=1(0<=i<m,0<=j<n)。最后path[m-1][n-1]即是最终结果。时间空间复杂度都是O(mn)。

    class Solution {
    public:
        int uniquePaths(int m, int n) {
            int res = 0;
            if(m <= 0 || n <= 0)
                return res;
            
            int** path = new int*[m];
            for(int i = 0; i < m; i++)
                path[i] = new int[n];
            
            for(int i = 0; i < m; i++)
                path[i][0] = 1;
            for(int i = 0; i < n; i++)
                path[0][i] = 1;
            
            for(int i = 1; i < m; i++)
            {
                for(int j = 1; j < n; j++)
                    path[i][j] = path[i - 1][j] + path[i][j - 1];
            }
            res = path[m - 1][n - 1];
            
            for(int i = 0; i < m; i++)
                delete[] path[i];
            delete[] path;
            
            return res;
        }
    };

    利用滚动数组可以将空间复杂度降为O(n):

    class Solution {
    public:
        int uniquePaths(int m, int n) {
            int res = 0;
            if(m <= 0 || n <= 0)
                return res;
            
            int* path = new int[n];
            for(int i = 0; i < n; i++)
                path[i] = 1;
            for(int i = 1; i < m; i++)
            {
                for(int j = 1; j < n; j++)
                    path[j] += path[j - 1];
            }
            res = path[n - 1];
            delete[] path;
            
            return res;
        }
    };

    外层循环使得path保存了移动到当前行的上一行所有位置的路径数目,因此内层循环只需要在加上当前列的左边列的路径数目即可。

  • 相关阅读:
    让VC6.0编译出来的程序支持XP样式或XP风格
    table+js实现网站左侧列表下拉隐藏
    图片或文件保存到数据库
    C#使用Cookie方法
    oracle实现今年数据 去年同期和增长百分比
    检索COM类工厂中CLSID为{000209FF-0000-0000-C000-000000000046}的组件时失败,原因是出现以下错误: 80070005
    oracle&&Sqlserver获取表名列名主键及数据类型
    sql中将null转换为空
    sql 游标
    oracle 提示口令失效解决方法
  • 原文地址:https://www.cnblogs.com/aprilcheny/p/4863344.html
Copyright © 2011-2022 走看看