Python算法例36 丑数Ⅱ

1. 问题描述

设计一个算法,找出只含素因子2、3、5的第n小的数,符合条件的数如:1、2、3、4、5、6、8、9、10、12…

2. 问题示例

如果n=9,返回10。

3. 代码实现

def find_nth_number(n):
    if n <= 0:
        return None

    numbers = [1]
    idx2 = 0  # 索引指向最后一个乘以2的数
    idx3 = 0  # 索引指向最后一个乘以3的数
    idx5 = 0  # 索引指向最后一个乘以5的数

    for _ in range(1, n):
        next_num = min(numbers[idx2] * 2, numbers[idx3] * 3, numbers[idx5] * 5)
        numbers.append(next_num)

        if next_num == numbers[idx2] * 2:
            idx2 += 1
        if next_num == numbers[idx3] * 3:
            idx3 += 1
        if next_num == numbers[idx5] * 5:
            idx5 += 1

    return numbers[-1]
print(find_nth_number(9))  # 输出:10
print(find_nth_number(15))  # 输出:24

上述代码使用“丑数”算法(Ugly Number Algorithm)。

它的核心思想是将数字拆分成若干个质因子的乘积,而这个算法只考虑素因子 2、3、5。具体来说,该算法使用动态规划的思想,维护三个指针 idx2、idx3 和 idx5 分别表示当前已经乘以 2、3、5 的数的索引位置,然后每次取三个指针指向的数中的最小值作为下一个丑数。

具体实现步骤如下:

  1. 定义一个列表 numbers,用于存储已经生成的丑数,初始化为 [1]。
  2. 定义三个指针 idx2、idx3 和 idx5,初始值都为 0。
  3. 从 1 开始循环,依次生成第 2、3、4、...、n 个丑数。
  4. 对于当前要生成的第 i 个丑数,其值等于三个指针指向的数中的最小值,即 min(numbers[idx2] * 2, numbers[idx3] * 3, numbers[idx5] * 5)。
  5. 将上一步生成的数添加到列表 numbers 中。
  6. 如果新生成的数等于 numbers[idx2] * 2,则将指针 idx2 加 1;如果等于 numbers[idx3] * 3,则将指针 idx3 加 1;如果等于 numbers[idx5] * 5,则将指针 idx5 加 1。
  7. 重复步骤 4~6,直到生成第 n 个丑数为止。
  8. 返回列表 numbers 中的最后一个数即为第 n 小的丑数。

这种算法的时间复杂度为 O(n),因为每次需要生成一个新的丑数,而且每个丑数都需要比较三个指针指向的数中的最小值。

Python算法例36 丑数Ⅱ_第1张图片

你可能感兴趣的:(python,开发语言,算法)