斐波那契 | 青蛙跳台阶问题 | 矩形覆盖问题 | 外加杨氏矩阵查找

刷题遇到了青蛙跳台阶,,,用到了斐波那契,,顺便从笔记上整理下。

 

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))

 

 

 

你可能感兴趣的:(算法)