原始题目链接:https://leetcode-cn.com/problems/ugly-number-ii/
给你一个整数 n ,请你找出并返回第 n 个 丑数 。
丑数 就是只包含质因数 2、3 和/或 5 的正整数。
示例 1:
输入:n = 10
输出:12
解释:[1, 2, 3, 4, 5, 6, 8, 9, 10, 12] 是由前 10 个丑数组成的序列。
示例 2:
输入:n = 1
输出:1
解释:1 通常被视为丑数。
解题思路:
动态规划,三步走,定义状态,dp[i]表示第i个丑数,初始化,第一个丑数是1,状态转移方程,后面的丑数都是由质因数2 3
5乘积得来的,因为要按照升序的顺序,所以每次取个最小值,同时也要去重,加条件判断(是否与当前丑数相等,再自增即可),具体实现看代码。
代码实现:
class Solution:
def nthUglyNumber(self, n: int) -> int:
# 定义状态dp[i]:表示第i个丑数
# 初始化dp数组
dp = [0] * (n + 1)
# 第一个丑数是1,索引1为第一个丑数位置
dp[1] = 1
# 定义3个指针,p2 p3 p5
# 因为后面的丑数是由当前的丑数乘以质因数2 3 5得来的
# 所以使用3个指针分别指向还没有乘以2 3 5的数
# p2 p3 p5初始化为第一个丑数1
# 下一个丑数就是dp[p2] * 2, dp[p3] * 3, dp[p5] * 5当中的最小值
# 如果dp[i]和 dp[p2] * 2, dp[p3] * 3, dp[p5] * 5某个相等,则
# 第i个丑数就是该值,并且将px自增一个位置,用于下一次计算丑数
# 并且要去重,例如2*5=10 5*2=10
p2, p3, p5, = 1, 1, 1
# 从第2个丑数位置开始找
for i in range(2, n + 1):
# 下一个可能的丑数
n1, n2, n3 = dp[p2] * 2, dp[p3] * 3, dp[p5] * 5
# 因为按升序,所以取最小
dp[i] = min(n1, n2, n3)
# 去重+自增位置,因为当前的丑数的乘法(乘2 3 或5)用过一次了
if dp[i] == n1:
p2 += 1
if dp[i] == n2:
p3 += 1
if dp[i] == n3:
p5 += 1
# 第一个丑数的位置是1,返回第n个丑数
return dp[n]
参考文献:
https://leetcode-cn.com/problems/ugly-number-ii/solution/chou-shu-ii-by-leetcode-solution-uoqd/