剑指offer#10斐波那契数列 && #10-2跳台阶 &&10-3跳台阶进阶问题 &&矩形覆盖

和自甴很熟 提交于 2019-12-02 02:36:36

大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。n<=39。

分析:使用递归会有很多重复计算,因此利用从下往上的思想,用循环来改进

class Solution {
public:
    int Fibonacci(int n) {
        int result[2] = {0,1};
        if(n<2)return result[n];
        int first=0,second=1,i=2,third ;
        while(i<=n){
            third = first + second;
            first = second;
            second = third;
            i++;
        }
        return third;
    }
};

**复杂度分析:

  1. 时间复杂度:O(n)
  2. 空间复杂度:O(1)

**

跳台阶:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

分析:假设n级台阶的跳法是f(n),那么最后一步可以是跳一个台阶,也可以是跳两个台阶,那么这样子的话f(n)由两种方式组成,一种是f(n-1)然后最后一步跳一个台阶,另一种是f(n-2)个台阶的跳法最后跳两个台阶.因此这其实也是斐波那契数列.

解法:

class Solution {
public:
    int jumpFloor(int number) {
        //青蛙一次可以跳1个或者2个台阶,因此假设n级台阶的跳法是f(n)
        //那么最后一步可以是跳1个台阶也可以是跳2个台阶,因此有两种方式组成f(n)
        //一种是f(n-1)然后跳一个台阶,另一种是f(n-2)跳两个台阶
        //因此可以得到f(n)=f(n-1)+f(n-2)
        int result[3] = {0,1,2};
        if(number<=2)return result[number];
        int first = 1,second = 2;
        int third;
        for(int i=3;i<=number;i++){
            third = first + second;
            first = second;
            second = third;
        }
        return third;
    }
};

**复杂度分析:

  1. 时间复杂度:O(n)
  2. 空间复杂度:O(1)

**

如果一次可以跳一级台阶,二级台阶。。。n级台阶,那么有多少种跳法。

分析:采用公式的话是2^(n-1).
否则:假设n级台阶有f(n)种跳法,那么f(n)可以由n种跳法得到,f(n)=1+f(1)+f(2)+…+f(n-1),其中f(1)=1,f(2)=2,因此可以用自下而上的数组的方法来累加求解.

#include<iostream>
#include<math.h>
using namespace std;
int main(){
    int n;
    cin>>n;
    int result[100] = {0,1,2};
    if(n<=3)
        cout<<result[n]<<endl;
    else{
        for(int i=3;i<=n;i++){
            result[i]=1;
            for(int j=1;j<i;j++){
                result[i]+=result[j];
            }
        }
        cout<<result[n]<<endl;
        cout<<pow(2.0,(double)(n-1))<<endl;
    }
}

**复杂度分析:

  1. 时间复杂度:O(n^2)
  2. 空间复杂度:O(n)

**

矩形覆盖:我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

分析:设2n的矩形的覆盖方法为f(n),而我们的21的小矩形可以横放可以竖放,因此
由两种方式组成,如果最左边是竖放,那么剩下的就是f(n-1),如果最左边是横放,
那么坐下必须横放,那么剩下的就是f(n-2)。
所以f(n) = f(n-1) + f(n-2)

class Solution {
public:
    int rectCover(int number) {
        //设2*n的矩形的覆盖方法为f(n),而我们的2*1的小矩形可以横放可以竖放,因此
        //由两种方式组成,如果最左边是竖放,那么剩下的就是f(n-1),如果最左边是横放,
        //那么坐下必须横放,那么剩下的就是f(n-2)。
        //所以f(n) = f(n-1) + f(n-2)
        int result[3] = {0,1,2};
        if(number<=2)return result[number];
        int first = 1,second = 2,third,i = 3;
        while(i<=number){
            third = first + second;
            first = second;
            second = third;
            i++;
        }
        return third;
    }
};

**复杂度分析:

  1. 时间复杂度:O(n)
  2. 空间复杂度:O(1)

**

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!