【算法】 动态规划 基础题库 1-7 python实现

本文介绍了使用Python实现动态规划解决基础算法问题,包括判断丑数、斐波那契数列、卡特兰数、贝尔数、二项式系数和排列系数。通过构建dp数组,逐一解析每个问题的解决方案,展示动态规划在计算各类型数列中的应用。
摘要由CSDN通过智能技术生成

丑数

丑数为仅有 2,3或5 的质因子的数。数列1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, … 展示了前11个丑数。按照惯例,其中包括1。给定一个数字n,请你找出第n个丑数。

首先,如何判断一个数是否为丑数?将这个数分别除以2、3、5的最大可能次幂,如果最终得到1,则为丑数。

因为丑数的质因子仅为2、3、5,丑数数列的数将会被分为三组:

  1. 1x2, 2x2, 3x2, 4x2, 5x2, …
  2. 1x3, 2x3, 3x3, 4x3, 5x3, …
  3. 1x5, 2x5, 3x5, 4x5, 5x5, …

每一个子数列都是丑数本身与2、3、5相乘。因此我们可以利用类似合并排序一样通过合并三个子数列来得到所有丑数。

  1. 声明丑数数列: ugly[n]

  2. 初始化第一个丑数: ugly[0] = 1

  3. 初始化三个子数列索引,指向子数列的第一个元素: i2 = i3 = i5 = 0

  4. 初始化三个下一个丑数的可能值:

    next_multiple_of_2 = ugly[i2] * 2;

    next_multiple_of_3 = ugly[i3] * 3;

    next_multiple_of_5 = ugly[i5] * 5;

  5. 填充dp数组

import time


def getNthUglyNo(n):
    ugly = [0] * n
    ugly[0] = 1
    i2 = i3 = i5 = 0

    next_multiple_of_2 = 2
    next_multiple_of_3 = 3
    next_multiple_of_5 = 5

    for i in range(1, n):
        ugly[i] = min(next_multiple_of_2,
                      next_multiple_of_3,
                      next_multiple_of_5)

        if ugly[i] == next_multiple_of_2:
            i2 += 1
            next_multiple_of_2 = ugly[i2] * 2

        if ugly[i] == next_multiple_of_3:
            i3 += 1
            next_multiple_of_3 = ugly[i3] * 3

        if ugly[i] == next_multiple_of_5:
            i5 += 1
            next_multiple_of_5 = ugly[i5] * 5

    return ugly[-1]


# Driver code
time_start = time.time()
no = getNthUglyNo(150)
time_end = time.time()
print('150th ugly no is', no)
print('cost ', (time_end - time_start) * 1000, 'ms')

由于时间复杂度为O(n), 所以用时已经没办法打印出来了。

斐波那契数列

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …
用数学术语来描述:
Fn = Fn-1 + Fn-2
种子数:F0 = 0, F1 = 1
给定一个数n,求第n个斐波那契数

和上一题类似,由下往上构建dp数组

def getNthFiboNo(n):
    Fibo = [0] * (n)
    Fibo[0] = 0
    Fibo[1] = 1
    if n <= 1:
        return Fibo[n]
    for i in range(2, n):
        Fibo[i] = Fibo[i - 2] + Fibo[i - 1]
    return Fibo[-1]


no = getNthFiboNo(9)
print('9th fibonacci no is', no)

# 9th fibonacci no is 21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值