「这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战」。
题目:给定一个m*n
的网格,起点在左上角,终点在右下角,要求找出所有可能的从起点到终点的路径。
解题思路
刚好去年学过组合数学,还是我导师教的~~本题就是组合数学组合数的题目,机器人从起点到终点,必然需要走的格子数为m+n-2
个,无非就是向下走和向右走,并且向下走和向右走的格子数是确定的,向下走个数为m-1
,向右走个数为n-1
,因此无论怎么走,其最终路径数为,因此只需计算此阶乘式即可,代码如下:
public int uniquePaths(int m, int n) {
if(m==1||n==1) return 1;
return (int)(factorial(m+n-2) / factorial(m-1) / factorial(n-1));
}
public long factorial(int n){
if(n==0) return 1;
return n*factorial(n-1);
}
上述代码无法通过,存在数的越界问题,可能是自己写的计算阶乘局限性比较大。既然直接计算阶乘不行,那么是否可以尝试换一个思路,如下阶乘:
,其直接计算方式为,首先需要计算之后还要计算和的阶乘,此时存在重复计算,实际上只需要计算从开始到的数相乘即可再除以的阶乘,换种思路计算:
是否可以从开始一直累加,累加到,而从累加,累加到,每次累加计算一部分,例如, 首先计算42*43/1
,以此类推,从而得到最终解,最终代码如下:
public int uniquePaths(int m, int n) {
long result = 1;
for(int x=m, y=1;y<n;x++, y++){
result = result*x / y;
}
return (int)result;
}
上述代码最终耗时0ms,击败百分之百Java提交用户,时间复杂度为,空间复杂度为。
最后
本题虽然是组合数学的一个知识点,但若想代码写出来则还需要更多的思考,比较亮眼的就是计算组合数的一种新的方式。