Day07统计每个月兔子的总数

134 阅读2分钟

Day7

有一种兔子,从出生后第3个月起每个月都生一只兔子,小兔子长到第三个月后每个月又生一只兔子。

例子:假设一只兔子第3个月出生,那么它第5个月开始会每个月生一只兔子。

一月的时候有一只兔子,假如兔子都不死,问第n个月的兔子总数为多少?

数据范围:输入满足 1≤�≤31 1≤n≤31

输入描述:

输入一个int型整数表示第n个月

输出描述:

输出对应的兔子总数

示例1

输入:

3

复制

输出:

2

思路分析:

  • 法1:经典的斐波那契数列,F(N) = F(N-1)+F(N-2),经典递归三部曲可以得出

    alt

相当于将每一层的和累计到上一层

  • 法2:迭代法实现,这个思路更简单,我们可以直接利用迭代,逐个记录F(i-2)和F(i-1)和F(i)的值,然后循环累加

具体实现:

#include <math.h>
#include <algorithm>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <stdlib.h>
#include <cstdlib>
#include <cstring>//#include "./include/list/sqlist.h"using namespace std;
/**
 * @description: 时间复杂度O(2^n) + 空间复杂度O(n)
 * @param {int} month
 * @return {*}
 */
int GetRabbitNums(int month){
    //典型递归题目
    //设置终止条件
    if(month == 1 || month == 2) return 1;
    else return GetRabbitNums(month-2)+GetRabbitNums(month -1); 
}
​
//法2迭代法
/**
 * @description: 时间复杂度O(n) + 空间复杂度O(1)
 * @param {int} month
 * @return {*}
 */
int GetRabbitNumsII(int month){
    //设置k1,k2,k3
    int k1 = 1;//第一个月
    int k2 = 1;//第二个月
    int ans = 0;//输出对应月份的答案
    if(month == 1 || month == 2) return 1;
    for(int i = 3; i <= month; i++){
        ans = k1 + k2;//累计答案
        k1 = k2;//更新第i-2个月的答案
        k2 = ans;//更新第i-1个月的答案
    }
    return ans;
}
​
int main(){
​
​
    // //day06
    // LinkList L;
    // int n;//输入数据数量
    // int index = 0;//输入的位置
    // ListNode* p;
    // while(scanf("%d",&n) != EOF){
    //     L = ListTailInsert(L,n);
    //     scanf("%d",&index);
    //     if(index == 0) std::cout << 0 << std::endl;
    //     else{
    //         p = FindKInListIII(L,index);
    //         if(p != NULL) printf("%d\n",p->data);
    //     }
    //     //PrintLinkedList(L);
    // }
    int month_;
    while(scanf("%d",&month_) != EOF){
        int ans = GetRabbitNumsII(month_);
        printf("%d\n",ans);
    }
    system("pause");
    return 0;
}

时间复杂度分析:

  • 法1:时间:O(2^n),空间O(n),证明连接
  • 法2:时间:O(n),空间O(n)

小结:

这种类型的题就是需要找到递归思路,就是每一层的运算是不是重复的,假如是重复的,那么就符合递归逻辑,但是递归的时间效率一般较慢,且鲁棒性差