代码题目记录之不同路径

137 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情

大家好 我是短袖撸码蒂尔尼。今天带来的是一道以前在LeetCode上的题目,题目难度不大。但我好久没做过这种题目了并且最近在进行代码题复习,就在此为大家分享一下解答思路。

题目阐述

题目在这里

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?

思路阐述

首先想到的应该是动态规划,我个人认为的动态规划的状态方程永远是:

F(n)=n+F(n1)F(n)=n+F(n-1)

因此我的解法是直接递归:

myuniquePaths=function(cr, cc, m, n){
    if(cr==m||cc==n){
        return 1
    }
    return myuniquePaths(cr+1,cc,m,n)+myuniquePaths(cr,cc+1,m,n)
}

var uniquePaths = function (m, n) {
    return myuniquePaths(1, 1, m, n)
};

然后超时了。

image.png

这我是没想到的。。。

第二种解法 杨辉三角

什么是杨辉三角捏

杨辉三角,是二项式系数在三角形中的一种几何排列。在欧洲,这个表叫做帕斯卡三角形。帕斯卡是在1654年发现这一规律的,比杨辉要迟393年,比贾宪迟600年。杨辉三角是中国古代数学的杰出研究成果之一,它把二项式系数图形化,把组合数内在的一些代数性质直观地从图形中体现出来,是一种离散型的数与形的结合。

他的特点如下:
前提:每行端点与结尾的数为1.

(与上图中的n不同,这里第一行定义为n=1)

  1. 每个数等于它上方两数之和。
  2. 每行数字左右对称,由1开始逐渐变大。
  3. 第n行的数字有n项。
  4. 前n行共[(1+n)n]/2 个数。
  5. 第n行的m个数可表示为 C(n-1,m-1) ,即为从n-1个不同元素中取m-1个元素的组合数。
  6. 第n行的第m个数和第n-m+1个数相等 ,为组合数性质之一。
  7. 每个数字等于上一行的左右两个数字之和。可用此性质写出整个杨辉三角。即第n+1行的第i个数等于第n行的第i-1个数和第i个数之和,这也是组合数的性质之一。即 C(n+1,i)=C(n,i)+C(n,i-1)
  8. (a+b)n的展开式中的各项系数依次对应杨辉三角的第(n+1)行中的每一项。
  9. 将第2n+1行第1个数,跟第2n+2行第3个数、第2n+3行第5个数……连成一线,这些数的和是第4n+1个斐波那契数;将第2n行第2个数(n>1),跟第2n-1行第4个数、第2n-2行第6个数……这些数之和是第4n-2个斐波那契数。
  10. 将第n行的数字分别乘以10^(m-1),其中m为该数所在的列,再将各项相加的和为11^(n-1)。11^0=1,11^1=1x10^0+1×10^1=11,11^2=1×10^0+2x10^1+1x10^2=121,11^3=1x10^0+3×10^1+3x10^2+1x10^3=1331,11^4=1x10^0+4x10^1+6x10^2+4x10^3+1x10^4=14641,11^5=1x10^0+5x10^1+10x10^2+10x10^3+5x10^4+1×10^5=161051。
  11. 第n行数字的和为2^(n-1)。1=2^(1-1),1+1=2^(2-1),1+2+1=2^(3-1),1+3+3+1=2^(4-1),1+4+6+4+1=2^(5-1),1+5+10+10+5+1=2^(6-1)。
  12. 斜线上数字的和等于其向左(从左上方到右下方的斜线)或向右拐弯(从右上方到左下方的斜线),拐角上的数字。1+1=2,1+1+1=3,1+1+1+1=4,1+2=3,1+2+3=6,1+2+3+4=10,1+3=4,1+3+6=10,1+4=5。
  13. 将各行数字左对齐,其右上到左下对角线数字的和等于斐波那契数列的数字。1,1,1+1=2,2+1=3,1+3+1=5,3+4+1=8,1+6+5+1=13,4+10+6+1=21,1+10+15+7+1=34,5+20+21+8+1=55。

说了这么多,那么我们这题怎么解呢?

杨辉三角的解法

因为递归的方法超时了,因此叫递归改变为循环,就能解决超时的问题。
由上面的第一点可知,每个数等于它上方两数之和。 因此最左侧一行和最顶侧一行的到达路径数都是1,而任何一个非该行列的节点都可以通过左侧节点和上侧节点的路径数相加得到从起点出发到达自己共有的路径数。

var uniquePaths = function(m, n) {
    let arr = Array(m).fill(0).map(item => Array(n).fill(1));
    arr[0][0] = 1;
    for (let i = 1; i < m; i++) {
        for (let j = 1; j < n; j++) {
            arr[i][j] = arr[i-1][j] + arr[i][j-1];
        }
    }
    return arr[m-1][n-1];
};

好了,这就是这道不同路径的解题思路。

我是短袖撸码蒂尔尼
一名热爱阿森纳的前端工程师
如果本文对您有帮助,可以给一个免费的赞吗?谢谢!

名片.jpg