前几天面试遇到一个关于兔子的面试题。回来上网一搜有很多类似的问题。于是就总结一下这类问题的解决方法。
题目:有一对兔子经过两个月长大,在第三个可以生下一对小兔子。 小兔子在经过两个月也可以生下一对小兔子。成年一对兔子每个月都可以生一对小兔子如果成年兔子可以无限生下去,问:第几个月有多少多少兔子?
实现代码:s
public static int GetCount(int monthNum)
{
if (monthNum <= 0) return 0;
// 能够生小兔子的成年兔
int canProduce = 0;
// 0个月大的小兔子
int zero= 2;
// 1个月大的小兔子
int one = 0;
// 成年兔
int adult = 0;
for (int i = 0; i < monthNum; i++)
{
// 本月具有生育能力的兔子数
canProduce = adult;
// 成年兔数
adult += one;
// 已经一个月大的兔子数
one = zero;
// 生育小兔子数
zero = canProduce;
}
return zero + one + adult;
}
根据上边的实现思路。其本质就是一个列表的移动。兔子从出生长到具有生育能力(可以是死亡,如果条件中有的话),就像一个传送带一样一个一个向后移动。根据这样的思路。我将上边的方法重构。
public static int GetCount(int monthNum)
{
if (monthNum <= 0) return 0;
// 能够生小兔子的成年兔
int canProduce = 0;
int[] rabbit = new int[3];
// rabbit[0] 0个月大的小兔子
// rabbit[1] 1个月大的小兔子
// rabbit[2] 成年兔
rabbit[0] = 2;
for (int i = 0; i < monthNum; i++)
{
canProduce = rabbit[2];
rabbit[2] += rabbit[1];
rabbit[1] = rabbit[0];
rabbit[0] = canProduce;
}
return rabbit[0] + rabbit[1] + rabbit[2];
}
这个实现方法,运用了数组移动。当然在移动过程中可能根据条件对数据进行处理如:生育期是2月3月,这样在计算canProduce 时稍作改变就像。如果有16月兔子就死亡。你可以将数据扩大,在到16月时将兔子数删除等等。