剑指offer(七,八),斐波拉切数列,跳台阶

题目描述
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。

大概所有同学C语言课程都敲过吧,那么这里我就不说那两个简单的方法,递归和迭代。

但是比较大的情况呢,甚至超过int范围,这就要考虑数学问题。
用矩阵计算的,在线性代数里的计算方法就是

这里写图片描述

n的次方结合矩阵快速幂,时间复杂度是logn,快速幂的时间复杂度,比普通的迭代n的复杂度低,也解决了大数的问题(数列后面的数太大要考虑使用long long类型)

#include <bits/stdc++.h>
using namespace std;

const int maxn = 4;
struct mat {
    int s[maxn][maxn];
    mat(){
        for(int i = 0; i < maxn; i++)
            for(int j = 0; j < maxn; j++) {
                s[i][j] = 0;
        }
    };
    mat operator * (const mat& c) {
    mat ans;
    for (int i = 0; i < maxn; i++) //矩阵乘法
        for (int j = 0; j < maxn; j++)
            for (int k = 0; k < maxn; k++)
                ans.s[i][j] = ans.s[i][j] + s[i][k] * c.s[k][j];
    return ans;
    }
}str;

mat pow_mod(int k) {
    if (k == 1)
        return str;
    mat a = pow_mod(k/2);//不能改
    mat ans = a * a;
    if (k & 1)
        ans = ans * str;
    return ans;
}

class Solution {
public:
    int Fibonacci(int n) {
        str.s[0][0] = 1;
        str.s[0][1] = 1;
        str.s[1][0] = 1;
        str.s[1][1] = 0;
        if(n==0)
            return 0;
        else {
            mat sub = pow_mod(n);
            int res = 0;
            res = sub.s[0][1];
            return res;
        }
    }
};

int main() {
    Solution *so = new Solution();
    cout<<so->Fibonacci(3)<<endl;
}

题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

其实也是斐波拉切数列的问题。

class Solution {
public:
    int jumpFloor(int number) {
        if(number==0) return 0;
        if(number==1) return 1;
        if(number==2) return 2;
        return jumpFloor(number-2) + jumpFloor(number-1);
    }
};
posted @ 2018-01-06 20:29  Lawliet__zmz  阅读(194)  评论(0编辑  收藏  举报