概述
第2章 面试需要的基础知识
面试题4:二维数组中的查找
面试题5:替换空格
面试题6:从尾到头打印链表
面试题7:重建二叉树
面试题9:用两个栈实现队列
面试题10:斐波那契数列
面试题11:旋转数组的最小值
第3章 高质量的代码
第4章 解决面试题的思路
第5章 优化时间和空间效率
第6章 面试中的各项能力
第7章 两个面试案例
题目描述
斐波那契数列:
F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)
现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
解题思路
暴力法就不介绍了。最常用解法是动态规划,这里递推式已经直接给出,编程时注意存储子问题解即可。
普通版:
class Solution:
def Fibonacci(self, n):
# write code here
if n < 0:
return None
if n == 0 or n == 1:
return n
f = [0] * (n+1)
f[0], f[1] = 0, 1
for i in range(2, n+1):
f[i] = f[i-1] + f[i-2]
return f[-1]
时间复杂度O(n),空间复杂度O(n)。上述解法只能说基本合格,仔细分析存储空间,发现每个值用过一次后就不用了,因此一直保存就显得很浪费,所以可以从减少空间复杂度入手,优化代码。
优化版:
class Solution:
def Fibonacci(self, n):
# write code here
if n < 0:
return None
if n == 0 or n == 1:
return n
pre, cur = 0, 1
for i in range(2, n+1):
temp = pre + cur
pre = cur
cur = temp
return cur
时间复杂度O(n),空间复杂度O(1)。用pre,cur分别保存f(n-2),f(n-1)的值。实际上可以把temp变量也直接省掉,如下:
class Solution:
def Fibonacci(self, n):
# write code here
if n < 0:
return None
if n == 0 or n == 1:
return n
pre, cur = 0, 1
for i in range(2, n+1):
cur, pre = pre + cur, cur
return cur
要注意的是需要考虑负数输入,因为题中只说了n是整数,而斐波那契数列中要求n>=0。
拓展训练
题目一:青蛙跳台阶
牛客网 跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
解题思路
和斐波那契数列一样,只是起始值略有不同。可以自己分析起始值。
实战
class Solution:
def jumpFloor(self, number):
# write code here
if number < 0:
return None
if number <= 2:
return number
pre, cur = 1, 2
for i in range(3, number+1):
cur, pre = cur + pre, cur
return cur
题目二:青蛙变态跳台阶
牛客网 变态跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
解题思路
动态规划:
与前面题稍有不同,这里递推式如下:
f(n)=f(n-1)+f(n-2)+……f(1)
如何保存好等式右边累加值是关键。
class Solution:
def jumpFloorII(self, number):
# write code here
if number < 0:
return None
if number <= 1:
return number
pre_total = 1
for i in range(2, number+1):
cur = pre_total + 1
pre_total = cur + pre_total
return cur
很多题目跳出计算机思维,使用数学方式可以更快得到结论。
数学法一:
易知 :
f(n)=f(n-1)+f(n-2)+……f(1)
f(n-1)=f(n-2)+……f(1)
两式相减得f(n)=2f(n-1)。这种方法本质上还是动态规划,只不过利用数学方法使得递推式更简单了。代码如下:
class Solution:
def jumpFloorII(self, number):
# write code here
if number < 0:
return None
if number <= 1:
return number
cur = 1
for i in range(2, number+1):
cur *= 2
return cur
数学法二:
f(n) = 2n-1
使用数学归纳法证明,因为:
f(1) =1 = 20;
f(2)=2=21;
f(3)=4=22;
假设 f(n-1)=2n-2成立,因为f(n)=2f(n-1)(前面已证明),所以可得:
f(n) = 2n-1
class Solution:
def jumpFloorII(self, number):
# write code here
if number <= 0:
return 0
return 2**(number-1)
题目三:矩形覆盖
我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
解题思路
牛客网
- n = 1 的时候
只能横着覆盖,一种 - n = 2 的时候
可以横着和竖着覆盖,两种 - n = 3 的时候
第三级横着覆盖,用了一级,剩下 n = 2,有两种覆盖方法
第三季竖着覆盖,用了两级,剩下 n = 1,有一种覆盖方法
总共有 3 种
… - n = n 的时候
第 n 级横着覆盖,用了一级,剩下 n = n - 1,所以关注第 n - 1 种有几种覆盖方法
第 n 级竖着覆盖,用了两级,剩下 n = n - 2,所以关注第 n - 2 种有几种覆盖方法
实际上还是斐波那契数列,就看能不能从具体问题中抽象出来。
class Solution:
def rectCover(self, number):
# write code here
if number < 0:
return None
if number <= 2:
return number
cur, pre = 2, 1
for i in range(3, number+1):
cur, pre = cur + pre, cur
return cur
最后
以上就是超帅糖豆为你收集整理的剑指offer 第二版(Python3)--面试题10:斐波那契数列,青蛙跳台阶,青蛙变态跳台阶,矩形覆盖的全部内容,希望文章能够帮你解决剑指offer 第二版(Python3)--面试题10:斐波那契数列,青蛙跳台阶,青蛙变态跳台阶,矩形覆盖所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复