小目标 To be or not to be

Leetcode 070 Climbing Stairs

2017-02-28
chaowyc

Leetcode 070 题

Difficulty:Easy

Tag: Dynamic Programming, Fibonacci

Climbing Stairs

题目原址:https://leetcode.com/problems/climbing-stairs/?tab=Description

You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

大意:假设你在爬楼梯,总共需要爬$n$个台阶才能到达顶部,但是一次只能爬一个或两个台阶,那么可以有多少种方式爬到顶部?

思路

先从最基础的开始:

if n <= 0, 爬楼梯的方式为 0
if n == 1, 爬楼梯的方式为 1
if n == 2, 爬楼梯的方式为 2 一次爬两个台阶 和 一次爬两个台阶爬两次

再来看结束的情况:

现在给定了总的台阶数n,如果我们知道爬到 第$n - 1$个台阶, 和 第$n - 2$个台阶的方式分别为 n1个, n2个,那么到达第 $n$ 个台阶的方式应该为 $n_1 + n_2$个

因为在 第$n - 1$个台阶时,只需要上一个台阶就可以到达 第 $n$ 个台阶

在 第 $n - 2$ 个台阶时,只需要上一次上两个台阶就可以到达 第 $n$ 个台阶

其实,分析到这里的时候,是不是有种似曾相识的感觉,是不是有斐波那契数列的影子,只不过数列开始前两项不是 1,1 而是 1, 2,但是满足斐波那契数列的性质–当前项的值为前两项的和。

所以,也就衍生出了第二种解法,就利用这种性质。

动态规划解法

设 $dp[i]$为到达第$i$个台阶的方式数

递推方程:

\(dp(i) = \begin{cases} dp[1] = 1, & \text{ i = 1} \\ dp[2] = 2, & \text{ i = 2 } \\ dp[i] = dp[i-1] + dp[i - 2], & \text{ i $\gt$ 2 } \end{cases}\)

class Solution {
public:
    int climbStairs(int n) {
        if(n <= 0) return 0;
        vector<int> dp(n);
        dp[0] = 1;
        dp[1] = 2;
        for(int i = 2; i < n; i++)
        {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n - 1];
    }
};

斐波那契解法

其实就是构造数组的过程

可以采用递归的构造方法,亦可以是迭代的构造方法

class Solution {
public:
    int climbStairs(int n) {
        if(n <= 0) return 0;
        if(n == 1) return 1;
        if(n == 2) return 2;
        int oneStep = 2;
        int twoStep = 1;
        int allStep = 0;
        for(int i = 2; i < n; i++)
        {
            allStep = oneStep + twoStep;
            twoStep = oneStep;
            oneStep = allStep;
        }
        return allStep;
    }
};

Similar Posts

Comments