• 爬楼梯与斐波那契数列


    今天做leetcode时,做到了爬楼梯问题:

    https://leetcode.com/problems/climbing-stairs/

    问题不再赘述。

      刚开始看到题的时候,就想着分析n级楼梯,直接得出答案。但是,在分析的过程中发现,若是对于一个常数n,且n不太大的情况下,利用排列组合的方法,也许可以得出结果,但是工作量大得无法想象,遂放弃排列组合。

      于是,老办法,n=1,n=2,n=3...发现竟然有点像斐波那契数列,于是,按照斐波那契数列的方法去做,果然ok!

      虽然得到了结果,但是偏执癌又犯了,为什么可以用斐波那契数列解决呢?思索之后,未得出满意的结果,遂查找资料:

      斐波那契数列,兔子生产与斐波那契数列,爬楼梯与斐波那契数列。。。

      (期间推敲了兔子生产的问题)

      在这个博客里 http://blog.csdn.net/ljsspace/article/details/6455293 给出了让人满意的分析:

      首先考虑第一步的走法:第一步可以走1级台阶,也可以走2级台阶。那么,设S(n)表示走n级台阶的走法数量,如果第一步走1级台阶,剩下的台阶数为n-1,也就是说这种情况下的走法是相当于S(n-1);同理,如果第一步走2级台阶,剩下的台阶数为n-2,这样的走法相当于S(n-2);于是,得出递推公式:

    S(n) = S(n-1) + S(n-2);

      接下来就很简单了:

    S(1)=1,S(2)=2;

      这下感觉圆满了!!

      

      不过,还是应当反思一下,为什么自己没有想到这样去分析呢?其实最初开始分析的时候,也是朝着这个方向去的,但是,思考一阵之后,没有得出满意答案,于是就放弃了。其实,这是一直都存在的毛病,确切说,应该是见得少的缘故,导致没有足够的经验,权衡之后,选择放弃,因为有可能是白白浪费时间和精力。事实证明,放弃的决定大多数是错误的:首先,对问题的“第一印象”是很重要的,往往就是从“第一印象”着手去分析,因为对于一个陌生的问题,也只能这样做;其次,随着分析的深入,从“第一印象”扩展开来,都会大致朝着正确的方向的,并逐渐接近问题的本质,那句话怎么说来着?透过现象看本质,现象是事物本质的外部表现,等等(理论学得不好),大概就是说通过现象去认识本质(词穷了);再次,在除去将要被“放弃”的方向之外,没有其他可以努力的方向时,就更不应该放弃了。

      还有一个问题:

      在实现过程中,使用两种方法:

      由于水平有限,“第一印象”只能想到这两种。

      方法一:

    class Solution {
    public:
        int climbStairs(int n) {
            
            if(n == 1){
                return 1;
            }else if(n == 2){
                return 2;
            }else{
                int n1 = 1, n2 = 2;
                int nf;
                for(int i = 2;i < n;++i){
                    nf = n1 + n2;
                    n1 = n2;
                    n2 = nf;
                }
                return nf;
            }
        }
    };

    方法二:

    class Solution {
    public:
        int climbStairs(int n) {
            
            if(n == 1){
                return 1;
            }else if(n == 2){
                return 2;
            }else{
                vector<int> buff;
                buff.push_back(1);
                buff.push_back(2);
                for(int i = 2;i < n;++i){
                    int temp = buff[i - 1] + buff[i - 2];
                    buff.push_back(temp);
                }
                return buff[n-1];
            }
    
        }
    };

      两种方法提交之后,方法二的Runtimes比方法一的要少,这说明使用法二性能比法一要好,就涉及到vector相关性能分析了,稍后再补上。

      如果有哪位能够给出一些指导,将不胜感激!

  • 相关阅读:
    ubuntu创建用户命令
    C#图像处理(各种旋转、改变大小、柔化、锐化、雾化、底片、浮雕、黑白、滤镜效果)
    Ubuntu14.04 64bit 编译安装nginx1.7+php5.4+mysql5.6
    ubuntu mysql 远程连接问题解决方法
    如何在LabWIndows/CVI中调用LabVIEW DLL
    NI MAX中缺少串口(转)
    LabWindows/CVI入门之第四章:库文件(转)
    c#中多线程同步Lock(锁)的研究以及跨线程UI的操作 (转)
    C# 实现生产者消费者队列 (转)
    Unity3d基于Socket通讯例子(转)
  • 原文地址:https://www.cnblogs.com/k-li/p/5543108.html
Copyright © 2020-2023  润新知