• 走台阶问题


    1,假设有n个台阶的楼梯,一个人要上这个楼梯,他每次可以走1个台阶或者2个台阶,问走上这个楼梯的走法总共有多少种?

       解答:这个题目可以从最简单的办法逐步掌握其规律,比如走上1个台阶总共只有1种走法,而走上2个台阶有两种走法(一种直接走2步,一种走2个一步),我们知道要走上第i个台阶,要么是从第i-1个台阶走一小步到的,要么是从第i-2个台阶走1大步。用F(i)表示走上第i个台阶的走法总数,那么F(1)=1,F(2)=2,那么F(i)是依赖于F(i-1)和F(i-2)的,其中 2<i<=n, 我们很容易知道 F(i)=F(i-1)+F(i-2)。也就是说我们最终问题的解为F(n)=F(n-1)+F(n-2),F(1)=1,F(2)=2.  了解斐波那契数列的人就知道这明显就是一个斐波那契数列。

    可以通过方程递归的求解问题:

    int Step(int n)//递归
    {
        if(n==1)
            return 1;
        else if (n==2)
            return 2;
        else 
            return Step(n-1)+Step(n-2);
    }

    这个过程的时间复杂度为O(2^n),我们可以用循环递推来改变这个时间代价:

    int func(int n)//时间复杂度是O(n)
    {
        int *a = new int[n];
        a[0] = 1;
        a[1] = 2;
        for (int i = 2;i<n;i++)
        {
            a[i] = a[i - 1] + a[i - 2];
        }
        int res = a[n - 1];
        delete[] a;
        return res;
    }

    对以上俩函数进行测试对比:

    #include<iostream>
    #include<time.h>
    using namespace std;
    
    int step(int n);//递归
    
    int func(int n);//改进
    
    int main(void)
    {
        clock_t start, finish;
        double  t1,t2;
        int ditui,diaoyong;
        start = clock();
        diaoyong= step(30);//假设30台阶
        cout << diaoyong << endl;
        finish = clock();
        t1 = (double)(finish - start) / CLOCKS_PER_SEC*1000000;
        cout <<"函数循环调用使用了"<< t1 << " 微秒" << endl;
        
        start = clock();
        ditui = func(30);
        cout << ditui << endl;
        finish = clock();
        t2= (double)(finish - start) / CLOCKS_PER_SEC * 1000000;
        cout <<"数组递推使用了"<< t2 << " 微秒" << endl;
        return 0;
    }

    测试结果对比

    2.一个人上台阶可以一次上1个,2个,或者3个,问这个人上n层的台阶,总共有几种走法?

    同样地我们也可以使用上述方法:

    //函数递归调用
    int step(int n)
    {
        if (n == 1)
            return 1;
        else if (n == 2)
            return 2;
        else if (n == 3)
            return 4;
        else
            return step(n - 1) + step(n - 2)+ step(n - 3);
    }
    //数组循环
    int func(int n)
    {
        int *a = new int[n];
        a[0] = 1;
        a[1] = 2;
        a[2] = 4;
        for (int i = 3;i<n;i++)
        {
            a[i] = a[i - 1] + a[i - 2]+ a[i - 3];
        }
        int res = a[n - 1];
        delete[] a;
        return res;
    }
  • 相关阅读:
    Oracle的rownum原理和使用
    ehcache 使用笔记
    @PostConstruct 注解
    Dubbo java.io.IOException: Can not lock the registry cache file
    java 学习 todoList
    因为本地没有配置 localhost 导致的 eclipse 的奇葩问题
    cheatsheet——mac 上的一款可以显示软件所有快捷键的小工具
    对象作为 map 的 key 时,需要重写 equals 方法和 hashCode 方法
    eclipse一直报An internal error occurred during: "Building workspace". GC overhead limit exceeded
    如何修改SVN客户端中保存的密码
  • 原文地址:https://www.cnblogs.com/Burgess-Fan/p/6803923.html
Copyright © 2020-2023  润新知