js-剑指刷题记录(递归和循环)

这篇博客记录了使用JavaScript解决斐波那契数列、跳台阶等算法问题的经验。作者通过递归和动态规划方法探讨了不同问题的解法,并分析了递归中的动态规划优化,如尾递归和动态规划状态转移方程。此外,还讨论了矩形覆盖问题,其解法与斐波那契数列有相似之处。
摘要由CSDN通过智能技术生成

1.斐波那契数列

大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。n<=39

我的解法

递归,在vscode跑了一下是没问题的,但是在牛客网上就运行时间过长了。运算量太大了,栈溢出。

function Fibonacci(n)
{
    if(n == 0) return 0
    if(n == 1) return 1
    if(n>=2&&n<=39){
        let x = Fibonacci(n-1)
        let y = Fibonacci(n-2)
        return x+y
    }
    return null
}
其他分析

题解中提到了很多办法,动态规划,柯里化,尾递归。
动态规划
力扣上的文章,写的很清楚
https://leetcode-cn.com/problems/fibonacci-number/solution/dong-tai-gui-hua-tao-lu-xiang-jie-by-labuladong/

function Fibonacci(n)
{
    if(n == 0) return 0
    if(n == 1) return 1
    let pre = 0
    let cur = 1
    for(let i=2;i<=n;i++){
        let sum = pre + cur
        pre = cur
        cur = sum
    }
    return cur
}

2.跳台阶

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

我的解法

其实做了上面那道题,这道题很好解了。
跳上n级台阶=跳上n-1级台阶再跳一级+跳上n-2级台阶再跳两级
这个不就是变种斐波那契数列嘛,利用动态规划思想就可以写出来了,当然递归也可以

function jumpFloor(number)
{
    if(number == 1) return 1
    if(number == 2) return 2
    let pre = 1
    let cur = 2
    for(let i=3;i<=number;i++){
        let sum = pre+cur
        pre = cur
        cur = sum
    }
    return cur
}

3.变态跳台阶

一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

我的解法

青蛙累死了。这道题不像算法题,更像一个数学题。
跳上n级f(n) = f(n-1)+f(n-2)+…+f(1)
跳上n-1级f(n-1) = f(n-2)+f(n-3)+…+f(1)
相减得f(n) =2f(n-1)

function jumpFloorII(number)
{
    if(number == 1) return 1
    let i = 1
    while(--number){//注意这里是--number
        i*=2
    }
    return i
}
一点补充

--a是前置型递减,返回自减之后的值
a--是后置型递减,返回自减之前的值

  var a = 3
  var c = a--
  console.log(a);  //2
  console.log(c);  //3
  

  var b = 3
  var d = --b
  console.log(b);  //2
  console.log(d);  //2

所以上述代码中while判断number自减之后的值,循环次数为n-1次,若是写成number–,那么循环就是n次了

4.矩形覆盖

我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
比如n=3时,2*3的矩形块有3种覆盖方法在这里插入图片描述

我的解法

这道题可以自然想到2n的矩形就是2(n-1)矩形加一块,肯定有点像斐波那契数列,然后就是画图归纳了。能得出f(n)=f(n-1)+f(n-2),当然还要考虑n为1和2的情况

function rectCover(number)
{
    if(number == 0) return 0
    if(number == 1) return 1
    if(number == 2) return 2
    let pre = 1
    let cur = 2
    for (let i=3;i<=number;i++){
        let sum = pre+cur
         pre = cur
         cur = sum
    }
    return cur
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值