刷题遇到了青蛙跳台阶,,,用到了斐波那契,,顺便从笔记上整理下。
1 打印第n位的斐波那契, 1 1 2 3 5 8 13 …… 有的是这样1 2 3 5 8 13 差不多
版本1
这个写起来很爽,用起来就很操蛋了,,效率太低,
def fib(n):
if n == 1 or n == 2:
return 1
return fib(n-1) + fib(n-2)
版本2
这个写得就很巧妙了,
def fib(n, l=[0]):
l[0] += 1
if n == 1 or n == 2:
l[0] -= 1
if l[0] == 0:
return 1
return 1, 1
else:
a, b = fib(n-1)
l[0] -= 1
if l[0] == 0:
return a+b
return b, a+b
2生成斐波那契数列
def fib(n):
l1 = [1, 1]
for i in range(n-2):
l1.append(l1[-2]+l1[-1])
return l1
2 青蛙跳台阶问题
描述:
一只青蛙一次可以跳上1级台阶,也可以一次跳2级台阶。求该青蛙跳上n级台阶总共有多少种跳法。
当了解到这道题和斐波那契数列有关系, 我真是一脸懵逼,,????
这只青蛙打算一共跳n级台阶
- 当n=1时, 有1种方法
- 当n=2时,有2种方法(1, 1), (2)
- 当n=3时,如果第一次跳1级,后面剩下的2级的跳法就是n=2时的两种;第二次跳2级,后面剩下的1级,就时n=1时的1种, 加起来就是1+2 =3 三种
- 以此类推, f(n) = f(n-1)+f(n-2)
不过这个斐波那契是变形的斐波那契,1,2,3,5,8……
fib = lambda n: n if n <= 2 else fib(n-1) + fib(n-2)
print(fib(5))
再不就这样
def fib(n):
if n <= 2:
return n
else:
return fib(n-1) + fib(n-2)
换汤不换药,一个东西。
3 变态青蛙跳台阶问题
这只青蛙吔屎了,自大了, 一次能跳n级台阶,,,求这只青蛙跳上n级台阶有几种方法。
- 一共1个台阶 f(1) = 1 只有一种跳法
- 一共2个台阶 f(2) = f(2-1)+f(2-2) 其中f(2-1)表示第一次跳1个台阶的跳法;f(2-2)表示第一次跳2个台阶的跳法
- 一共3个台阶 f(3) = 3 = f(3-1)+f(3-2)+f(3-3) 其中f(3-1)表示第一次跳1个台阶的跳法;f(3-2)表示第一次跳2个台阶的跳法;f(3-3)表示第一次跳3个台阶的跳法
- 一共4个台阶 f(4) = 5 = f(4-1)+f(4-2) 其中f(4-1)表示第一次跳1个台阶的跳法;f(4-2)表示第一次跳2个台阶的跳法;f(4-3)表示第一次跳3个台阶的跳法;f(4-4)表示第一次跳4个台阶的跳法
- ……
- n级台阶,f(n)=f(n-1)+f(n-2)+f(n-3)……+f(0)
- 那么可以算出f(n-1)=f(n-2)+f(n-3)+……+f(0)
- f(n)-f(n-1)=f(n-1)
- f(n)=2*f(n-1)
所以代码
fib = lambda n: n if n < 2 else 2 * fib(n-1)
print(fib(4))
4 矩形覆盖问题
描述: 我们可以用2*1的小矩形横着或竖着去覆盖更大的矩形。请问用n个2*1的小矩行无重复地覆盖一个2*n地大矩形,总共有多少种方法?
这其实又是斐波那契的变种,(最晚都写完了,好像忘记保存了,,草稿箱也没提有,)
- 当n=1时,只能横着放, 1种方法
- 当n=2时,可以都横着放或者都竖着放,2中方法
- 当n=3时, 可以1横2竖,或者2竖1横,或者3横。共3种方法。
- n时,①当你最后一块打算横着放时,那么方法数等于f(n-1)。②当你最后一块打算竖着放,那么你倒数第二块必须也是竖着放的,那总共的方法数就是f(n-2)。
- 所以f(n)=f(n-1)+f(n-2)
fib = lambda n: n if n <= 2 else fib(n-1) + fib(n-2)
5 杨氏矩阵查找
在一个m行n列二维数组中,每一行都按照从左到右递增的顺序排列,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
(这个题目就是让你输入一个杨氏矩阵,然后在输一个数,看看在不在里面,不要多想,而且保证自己输入正确, 不要给自己找麻烦)
def get_value(l, r, c):
return l[r][c]
def find(l, x):
m = len(l) - 1 # 行数
n = len(l[0]) - 1 # 列数
r = 0 # 默认从0行开始
c = n # 默认从最后一列开始
while c >= 0 and r <= m:
value = get_value(l, r, c)
# 从右上的数开始
if value == x:
return True
elif value > x:
# 所选值大于x, 列数-1,因为这一行前面的数都别value小
c = c - 1
elif value < x:
# 所选值小于x, 行数+1, 因为这一列下面的数都比value大
r = r + 1
return False
print(find([[1,4,7,11,15], [2,5,8,12,19], [3,6,9,16,22], [10,13,14,17,24], [18,21,23,26,30]], 9))