剑指offer 49 - 丑数 - python

94 阅读1分钟

题目描述:

我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。

示例:

输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。

说明:

  • 1 是丑数。
  • n 不超过1690。

丑数只包含质因子2,3,5,假设我们已经有 n n n个丑数,按照顺序排列,且第 n n n的丑数为 M M M。那么,第 n + 1 n+1 n+1个丑数一定是由这 n n n个丑数分别乘以2,3,5,得到的所有大于 M M M的结果中,最小的那个数。

事实上,我们不需要每次都计算前面所有丑数乘以2,3,5的结果,然后再比较大小。因为在已存在的丑数中,一定存在某个数 m 2 m_2 m2​(在代码中用nums[f2]表示,f2表示需要乘以2的丑数的位置),在它之前的所有数乘以2都小于已有丑数,而 m 2 × 2 m_2×2 m2​×2的结果一定大于最大的丑数,同理,也存在这样的数 m 3 m_3 m3​, m 5 m_5 m5​,我们只需要标记这三个数即可。

class Solution:
    def nthUglyNumber(self, n: int) -> int:
        if n < 1: return n

        nums = [1] * n
        f2, f3, f5 = 0, 0, 0

        for i in range(1, n):
            nums[i] = min(nums[f2] * 2, nums[f3] * 3, nums[f5] * 5)

            if nums[i] == nums[f2] * 2: f2 +=  1
            if nums[i] == nums[f3] * 3: f3 +=  1
            if nums[i] == nums[f5] * 5: f5 +=  1

        return nums[-1]