矩形格路径的个数 Unique Paths

来源:互联网 发布:cf提示网络异常 编辑:程序博客网 时间:2024/05/20 06:05

题目源自于leetcode。

题目: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?


本题思路:

    对于m行n列的矩形,从左上角走到右下角需要走m-1+n-1步,其中m-1步是向下的,n-1步是向右的,这m-1+n-1步中的向下和向右任意组合,很明显存在的路径个数是组合数C(m-1+n-1, m-1)

    从图的角度来看,可以采用由小到大的递推思想进行,先考虑最接近右下角的点到目的地的路径个数,然后依次递推,逐步扩散直到左上角。


代码一:递推方式

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


代码二:数学公式

    数学方法求组合数C(m-1+n-1, m-1)。求组合数的时候注意,按平常的求法,我是先求分子上的积,然后求分子的积,然后相除。但是在程序运行的时候如果这样做,容易导致运算乘法的时候溢出。所以我乘法和除法交叉进行,使得结果始终不会溢出。此时又产生一个问题,虽然最终的组合数一定是个整数,但是交叉乘除的中间过程可能产生小数,所以我用浮点数来做。最终结果需要再转换为整数。

    最终的结果可能是这样的两种情况,比如10.99,需要转换为11;又如10.00,需要转换为10。显然这两个的转换策略是不同的,需要区分开。

class Solution {public:    int uniquePaths(int m, int n) {    if(m == 0 || n==0)        return 0;    double result = 1;    int i;    for(i=0;i<m-1;i++)    {        result *= m + n - 2 - i; result /= m-1-i;    }if(result - (int)result > 0.01)return result + 1;elsereturn result;    }};

上面两种方式比较起来:递推方式的时间性能好一些,因为只是做加法, 但是需要有O(m*n)的空间消耗;数学方法的空间性能是O(1),由于需要乘法和除法,所以时间上要比递推方式差一点点。


问题扩展:对上面的问题的条件加强,要求格路径必须只在矩形的一个反对角线的单独一侧,求满足这种要求的路径数。

    显然这种情况下的路径数要比之前的问题的路径数少一些,但绝对不是它的一半。

    如果矩形是正方形,那么该问题属于catalan数的问题(在另一篇博文中);

    如果矩形不是正方形,那么是组合数学的又一个问题,可以直接参考定理8.5.3:




原创粉丝点击