返回
LeetCode 每日一题:丑数(No.263)的精彩解读
见解分享
2023-11-23 06:41:56
题目
给定一个正整数 n,请找出第 n 个丑数。
丑数是指只包含质因数 2、3 和 5 的正整数。
示例
输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。
思考
丑数的生成方式有很多种。这里我们介绍一种简单易懂的方法:
- 从 1 开始,依次乘以 2、3 和 5,得到新的数字。
- 将这些新数字与之前的丑数进行比较,如果它们是丑数,就将其添加到丑数列表中。
- 重复以上步骤,直到丑数列表中包含 n 个丑数。
实现
def is_ugly(num):
"""
判断一个数字是否为丑数。
参数:
num: 要判断的数字。
返回:
如果 num 是丑数,返回 True,否则返回 False。
"""
# 如果 num 是 0,则它不是丑数。
if num == 0:
return False
# 如果 num 可以被 2、3 或 5 整除,则它一定是丑数。
while num % 2 == 0:
num //= 2
while num % 3 == 0:
num //= 3
while num % 5 == 0:
num //= 5
# 如果 num 不可以被 2、3 或 5 整除,则它不是丑数。
return num == 1
def get_ugly_number(n):
"""
获取第 n 个丑数。
参数:
n: 要获取的丑数的序号。
返回:
第 n 个丑数。
"""
# 初始化丑数列表。
ugly_numbers = [1]
# 依次乘以 2、3 和 5,得到新的数字。
while len(ugly_numbers) < n:
# 计算下一个丑数的候选数字。
candidates = [ugly_numbers[-1] * 2, ugly_numbers[-1] * 3, ugly_numbers[-1] * 5]
# 从候选数字中选择最小的丑数。
min_ugly_number = min(candidates)
# 将最小的丑数添加到丑数列表中。
ugly_numbers.append(min_ugly_number)
# 返回第 n 个丑数。
return ugly_numbers[n - 1]
if __name__ == "__main__":
# 测试 is_ugly 函数。
print(is_ugly(6)) # True
print(is_ugly(8)) # True
print(is_ugly(14)) # False
# 测试 get_ugly_number 函数。
print(get_ugly_number(10)) # 12
print(get_ugly_number(100)) # 1536
丑数的性质
丑数具有以下性质:
- 1 是丑数。
- 丑数的乘积也是丑数。
- 丑数的因子一定是 2、3 和 5。
- 丑数的个数是无限的。
数据结构
在这道题中,我们可以使用列表来存储丑数。
动态规划
这道题也可以使用动态规划来解决。具体做法是:
- 定义一个 dp 数组,其中 dp[i] 表示第 i 个丑数。
- 初始化 dp 数组:dp[1] = 1。
- 对于 i 从 2 开始到 n,计算 dp[i]:
- 将 dp[2 * i