算法 LC 动态规划 - 爬楼梯

题目描述

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

示例 1:
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1 阶 + 1 阶
2 阶

示例 2:
输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1 阶 + 1 阶 + 1 阶
1 阶 + 2 阶
2 阶 + 1 阶

题解

思路1: 动态规划

设dp[i]为爬到i阶的不同方法数
dp[i]的转移方程为:
dp[i] = dp[i-1]+dp[i-2] (i>2)
边界条件:dp[1]=1,dp[2]=2

// OC
+ (int)climbStairs1:(int)n {
    if (n <= 2) {
        return n;
    }
    
    int dp[n+1];
    dp[1] = 1;
    dp[2] = 2;
    
    for (int i=3; i
// Swift
    static public func climbStairs1(_ n:Int) -> Int {
        if n <= 2 {return n}
        var dp = Array(repeating: 0, count: n+1)
        dp[1] = 1
        dp[2] = 2

        for i in 3..<(n+1){
            dp[i] = dp[i-1] + dp[i-2]
        }
        return dp[n]
    }

思路2:通项公式

设f(n)为爬到n阶的不同方法数
f(n) =f(n-1)+f(n-2) (n>2)
f(1) = 1 f(2)= 1 f(3) = 2
f(n)是齐次线性递推,根据递推公式f(n) = f(n-1)+f(n-2),我们可以写出这样的特征方程
x*x=x+1,求得x1 = (1+ √5)/2,x2 = (1-√5)/2。设通解为f(n) = c1x1^n + c2x2^n,代入初始条件f(1) = 1,f(2) = 1,
得c1 = 1/(√5),c2 = -1/(√5),我们得到了这个递推数列的通项公式

f(n) = 1/√5*(((1+√5)/2)^n - ((1-√5)/2)^n)

// OC
+ (int)climbStairs2:(int)n {
    double sqrt5 = sqrt(5);
    double fibn = pow((1+sqrt5)/2, n+1) - pow((1-sqrt5)/2, n+1);
    int res = (int)round(fibn/sqrt5);
    return res;
}
// Swift
    static public func climbStairs2(_ n:Int) -> Int {
        let sqrt5:Double = sqrt(5)
        let fibn:Double = pow((1+sqrt5)/2, Double(n+1)) - pow((1-sqrt5)/2, Double(n+1))
        let res:Int = Int(round(fibn/sqrt5))
        return res
    }

参考:https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/xn854d/

https://leetcode-cn.com/problems/climbing-stairs/solution/pa-lou-ti-by-leetcode-solution/

你可能感兴趣的:(算法 LC 动态规划 - 爬楼梯)