斐波那切数列面试题

88 阅读1分钟

有一段楼梯有50级台阶,规定每一步只能跨1阶或2级,要登上第 50 级台阶有几种不同的走法?

解题思路:

  1. 登上第1阶有1种方法;
  2. 登上第2阶可以是1步1阶,也可以是1步2阶,有2种走法;
  3. 登上第3阶可以是由第1阶一步2阶,或者由第2阶一步1阶;
  • 以此类推
  • f(1) = 1
  • f(2) = 2
  • f(n) = f(n-1) + f(n-2) (n>=2)

代码实现:

递归实现:

//存放已经计算过的结果,避免重复计算,这样减少了递归的调用次数
var dictM = [Int:Int]()
func calculateMethods(n: Int) -> Int {
    if n<=2 {
        return n
    }
    var oneV = 0
    let firstIndex = n - 1
    //查看n-1的次数,如果有直接获取,如果没有就计算并存到表内
    if dictM.keys.contains(firstIndex) {
        oneV = dictM[firstIndex] ?? 0
    } else {
        oneV = methodM(n: firstIndex)
        dictM[firstIndex] = oneV
    }

    var twoV = 0
    let secondIndex = n - 2
    //查看n-2的次数,如果有直接获取,如果没有就计算并存到表内
    if dictM.keys.contains(secondIndex) {
        twoV = dictM[secondIndex] ?? 0
    } else {
        twoV = methodM(n: secondIndex)
        dictM[secondIndex] = twoV
    }
    return oneV + twoV
}

非递归实现

func calculateMethods(n: Int) -> Int {
    //初始代表第0阶的方法数,值初始为1是逆向有第2阶方法数减第1阶方法的所得
    var a = 1 
    //初始代表第1阶方法数
    var b = 1 
    //n阶的方法数
    var sum = 0
    for i in 2 ... n {
        sum = a + b
        if i%2 == 0 {
        //将偶数阶的方法数赋值给a
            a = sum
        } else {
        //将奇数阶的方法数赋值给b
            b = sum
        }
    }
    return sum
}