LeetCode70. 爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

示例 1:

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

示例 2:

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

这个问题恰好在阿里电话面试的时候被问到,本渣确实很渣,而且leetcode没有怎么刷哈哈哈哈哈,就比较惨。

听到这个题我隐隐觉得不妙,本渣不怎么会动态规划,抱着必死的决心听完题目。

首先的想法是,这个题比较类似给你1元2元5元10元...让你凑100元有多少种凑法。我就说了“暴力破解”,然后讲了一下大致思路。小哥哥说“这个复杂度是不是有点高”。我说“emmm,是的”。经过本渣实验,这个不仅仅是复杂度的问题,在某种层面上讲,这个题目不是很适合用暴力,因为会考虑不周,将“先走一步,再走两步”和“先走两步,再走一步”这种类似情况判为同一种方案。

//暴力破解考虑不到1.2;2.1的情况
class Solution {
public:
    int climbStairs(int n) 
    {
        int count=0;
        for(int i=0;i<=n;i++)
        {
            for(int j=0;j<=(n/2);j++)
            {
                if((i+(j*2))==n)
                    count++;
            }
        }
        return count;      
    }
};

而后,本渣给小哥哥说,我们不然可以直接套用排列组合的公式,直接计算出对应的结果。事实证明,后面还有一种公式方法证明野蛮生长才是最好的方法。

小哥哥说是一种方案,而后,本渣求助了一下度老师,看到了递归,动态规划基本就是靠递归。我说“递归比较费空间”,小哥哥说“空间不要紧了,现在这么发达了”。咳咳,空间还是要紧的,不信,下面的代码就超出运行时间限制了。然后小哥哥引导我“斐波那契数列”,我了解啊,生兔子的故事,度老师递归那里也讲了,S(N)=S(N-1)+S(N-2)。嗯,小哥哥最终终于放过我了。事实证明,其实单纯递归并不好,会超出限制。但是思路的广度还是比较重要的。

//直接递归会超出时间限制
class Solution {
public:
    int climbStairs(int n) 
    {
        if(n==1)
            return 1;
        if(n==2)
            return 2;
        return climbStairs(n-1)+climbStairs(n-2);        
    }
};

在实验过程中,决定采用迭代的方案依托“斐波那契”进行求解。获得了胜利,主体思路还是生兔子哈哈哈哈哈哈。

//AC代码迭代法
class Solution {
public:
    int climbStairs(int n) 
    {
        int nums=0;
        int one=1,two=2;
        if(n==1)
            return 1;
        if(n==2)
            return 2;
        for(int i=3;i<=n;i++)
        {
            nums=one+two;
            one=two;
            two=nums;
        }
        return nums;
    }
};

最后,一种也蛮生长的方案:“斐波那契数列”通项公式,就是涉及0.618和1.618的那个表达式。这个大佬的BLOG里面有写,代码直接用的大佬的了。其实讲道理,我最喜欢这个大佬的方式,太直接了。哈哈哈。

https://blog.csdn.net/u010412858/article/details/79790176

 

class Solution {
public:
    int climbStairs(int n) 
    {
        n++;
        double root5 = sqrt(5);
        double result = 1 / root5*(pow((1 + root5) / 2, n) - pow((1 - root5) / 2, n));
        return (int)(result);
    }
};

 

你可能感兴趣的:(LeetCode)