矩形格路径的个数 Unique Paths

142 篇文章 20 订阅
44 篇文章 1 订阅

题目源自于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;
	else
		return result;
		
    }
};

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


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

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

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

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




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值