Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

斐波那契数列 #33

Open
xuexueq opened this issue Dec 28, 2018 · 0 comments
Open

斐波那契数列 #33

xuexueq opened this issue Dec 28, 2018 · 0 comments
Labels
剑指offer 剑指offer 数据结构与算法 数据结构与算法

Comments

@xuexueq
Copy link
Owner

xuexueq commented Dec 28, 2018

题目1

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

地址

https://www.nowcoder.com/practice/c6c7742f5ba7442aada113136ddea0c3?tpId=13&tqId=11160&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-rankingg

题目2

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

地址:https://www.nowcoder.com/practice/8c82a5b80378478f9484d87d1c5f12a4?tpId=13&tqId=11161&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-rankingg&tPage=1

分析:首先考虑最简单的情况。如果只有1级台阶,那显然只有一种跳法。如果有2级台阶,那就有两种跳的方法了:一种是分两次跳,每次跳1级;另外一种就是一次跳2级。

现在我们再来讨论一般情况。我们把n级台阶时的跳法看成是n的函数,记为f(n)。

  • 当n>2时,第一次跳的时候就有两种不同的选择:
  • 一是第一次只跳1级,此时跳法数目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1);
  • 另外一种选择是第一次跳2级,此时跳法数目等于后面剩下的n-2级台阶的跳法数目,即为f(n-2)。

因此n级台阶时的不同跳法的总数f(n)=f(n-1)+f(n-2)。

我们把上面的分析用一个公式总结如下:

        /  1                             n = 1
f(n)=      2                             n = 2
        \  f(n-1) + f(n-2)               n > 2

那么,如果一个人上台阶可以一次上1个,2个,或者3个呢?这个时候,公式是这样写的:

        / 1                                      n = 1
f(n)=     2                                      n = 2
          4                                      n = 3       //111, 12, 21, 3
        \ f(n-1)+f(n-2)+f(n-3)                   n > 3

兔子繁殖问题

13世纪意大利数学家斐波那契在他的《算盘书》中提出这样一个问题:有人想知道一年内一对兔子可繁殖成多少对,便筑了一道围墙把一对兔子关在里面。已知一对兔子每一个月可以生一对小兔子,而一对兔子出生后.第三个月开始生小兔子假如一年内没有发生死亡,则一对兔子一年内能繁殖成多少对?

分析:这就是斐波那契数列的由来,本节的跳台阶问题便是此问题的变形,只是换了种表述形式。

题目3

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

地址: https://www.nowcoder.com/practice/22243d016f6b47f2a6928b4313c85387?tpId=13&tqId=11162&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-rankingg&tPage=1

分析:

关于本题,前提是n个台阶会有一次n阶的跳法。分析如下:

f(1) = 1
f(2) = f(2-1) + f(2-2) //f(2-2) 表示2阶一次跳2阶的次数。
f(3) = f(3-1) + f(3-2) + f(3-3)
...
f(n) = f(n-1) + f(n-2) + f(n-3) + ... + f(n-(n-1)) + f(n-n)

说明:

1)这里的f(n) 代表的是n个台阶有一次1,2,...n阶的 跳法数。
2)n = 1时,只有1种跳法,f(1) = 1
3) n = 2时,会有两个跳得方式,一次1阶或者2阶,这回归到了问题(1) ,f(2) = f(2-1) + f(2-2)
4) n = 3时,会有三种跳得方式,1阶、2阶、3阶,
那么就是第一次跳出1阶后面剩下:f(3-1);第一次跳出2阶,剩下f(3-2);第一次3阶,那么剩下f(3-3)
因此结论是f(3) = f(3-1)+f(3-2)+f(3-3)
5) n = n时,会有n中跳的方式,1阶、2阶...n阶,得出结论:
f(n) = f(n-1)+f(n-2)+...+f(n-(n-1)) + f(n-n) => f(0) + f(1) + f(2) + f(3) + ... + f(n-1)
6) 由以上已经是一种结论,但是为了简单,我们可以继续简化:
f(n-1) = f(0) + f(1)+f(2)+f(3) + ... + f((n-1)-1) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2)
f(n) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2) + f(n-1) = f(n-1) + f(n-1)
可以得出:
f(n) = 2*f(n-1)
7) 得出最终结论,在n阶台阶,一次有1、2、...n阶的跳的方式时,总得跳法为:

n=0, f(n) = 1;
n = 1, f(n) = 1;
n >=2, f(n) = 2 * f(n-1)

除了最后一级台阶必须要跳外,每级台阶都存在跳与不跳两种情况,所以共有2^(n-1)中跳法。

即数学问题, n个台阶最多有n-1个分段, 每个分段可以跳也可以不跳,所以有2的n-1次方

每个台阶可以看作一块木板,让青蛙跳上去,n个台阶就有n块木板,最后一块木板是青蛙到达的位子,必须存在,其他 (n-1) 块木板可以任意选择是否存在,则每个木板有存在和不存在两种选择,(n-1) 块木板 就有 [2^(n-1)] 种跳法,可以直接得到结果。

其实我们所要求的序列为:0,1,2,4,8,16,……
所以除了第一位外,其他位的数都是前一位的数去乘以2所得到的积。

题目4

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

地址: https://www.nowcoder.com/practice/72a5a919508a4251859fb2cfb987a0e6?tpId=13&tqId=11163&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-rankingg&tPage=1

分析:

第一种情况等价于情形1中阴影部分的n-1块矩形有多少种覆盖方法,为f(n-1);

第二种情况等价于情形2中阴影部分的n-2块矩形有多少种覆盖方法,为f(n-2);

故f(n) = f(n-1) + f(n-2),还是一个斐波那契数列。。。。

且f(1) = 1, f(2) = 2。

我们采用从能够简单到复杂的思路思考这个问题,
当n=1的时候,只有一个21的矩形,所以只有一种方法,记为f(1)=1;
当n=2的时候,是两个2
1的矩形,这时候具有两种方式去覆盖这个矩形了(这时候应该是一个正方形),一种是竖着放,一种是横着放,所以有两种方法,记为f(2)=2;
当n=3的时候,仍然只能采用横着放或者竖着放的方式去覆盖这个矩形,我们仍首先考虑使用竖着放的方式,当竖着放的时候,由于已经覆盖了左边(假设是从左边开始覆盖的,从右边的覆盖的效果是一样的)一个21的矩形,所以还有2个21的矩形,而这种情况我们已经在n=2的时候计算出来了,就是f(2);接下来我们考虑横着放的情况,由于是横着放,在水平方向已经覆盖了一个21的矩形,所以要想覆盖这由3个21组成的矩形,只能在水平方向的覆盖的那个矩形下面继续覆盖一个,那么只剩下一个2*1的矩形了,这也通过前面的分析计算出来了,就是f(1)。
综合以上分析,当n=3的时候,覆盖的方法是f(3)=f(1)+f(2)。

其他以此类推,我们发现这仍然是一个斐波那契数列

@xuexueq xuexueq added 剑指offer 剑指offer 数据结构与算法 数据结构与算法 labels Dec 28, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
剑指offer 剑指offer 数据结构与算法 数据结构与算法
Projects
None yet
Development

No branches or pull requests

1 participant