本文目录
- [1 中文题目](#1 中文题目)
- [2 求解思路](#2 求解思路)
-
- [2.1 基础解法:除法取余法](#2.1 基础解法:除法取余法)
- [2.2 优化解法:模式匹配法](#2.2 优化解法:模式匹配法)
- [2.3 最优解法:硬编码法](#2.3 最优解法:硬编码法)
- [3 题目总结](#3 题目总结)
1 中文题目
七个不同的符号代表罗马数字,其值如下:
符号 | 值 |
---|---|
I | 1 |
V | 5 |
X | 10 |
L | 50 |
C | 100 |
D | 500 |
M | 1000 |
罗马数字是通过添加从最高到最低的小数位值的转换而形成的。将小数位值转换为罗马数字有以下规则:
- 如果该值不是以
4
或9
开头,请选择可以从输入中减去的最大值的符号,将该符号附加到结果,减去其值,然后将其余部分转换为罗马数字。 - 如果该值以
4
或9
开头,使用减法形式
,表示从以下符号中减去一个符号,例如4 是 5 (V) 减 1 (I): IV ,9 是 10 (X) 减 1 (I):IX
。仅使用以下减法形式:4 (IV),9 (IX),40 (XL),90 (XC),400 (CD) 和 900 (CM)
。 - 只有
10
的次方(I, X, C, M)
最多可以连续附加3
次以代表10
的倍数。不能多次附加5 (V),50 (L) 或 500 (D)
。如果需要将符号附加4
次,请使用减法形式
。
给定一个整数,将其转换为罗马数字。
示例 1:
python
输入:num = 3749
输出: "MMMDCCXLIX"
解释:
3000 = MMM 由于 1000 (M) + 1000 (M) + 1000 (M)
700 = DCC 由于 500 (D) + 100 (C) + 100 (C)
40 = XL 由于 50 (L) 减 10 (X)
9 = IX 由于 10 (X) 减 1 (I)
注意:49 不是 50 (L) 减 1 (I) ,因为转换是基于小数位
示例 2:
python
输入:num = 58
输出:"LVIII"
解释:
50 = L
8 = VIII
示例 3:
python
输入:num = 1994
输出:"MCMXCIV"
解释:
1000 = M
900 = CM
90 = XC
4 = IV
提示:
- 1 ≤ n u m ≤ 3999 1\leq num \leq 3999 1≤num≤3999
2 求解思路
2.1 基础解法:除法取余法
思路
将数字按位分解(千位、百位、十位、个位),对每个位置上的数字分别处理,根据不同位置的权重选择对应的罗马数字字符,最后将所有位置的结果组合。
详细算法步骤:
- 千位处理(1000-3000):
- 除以1000获取千位数字,重复相应次数的M
- 百位处理(100-900):
- 对1000取余后除以100获取百位数字
- 根据数值选择处理方式:
- 900:使用CM
- 500-800:使用D加若干个C
- 400:使用CD
- 100-300:使用若干个C
- 十位处理(10-90):
- 对100取余后除以10获取十位数字
- 根据数值选择处理方式:
- 90:使用XC
- 50-80:使用L加若干个X
- 40:使用XL
- 10-30:使用若干个X
- 个位处理(1-9):
- 对10取余获取个位数字
- 根据数值选择处理方式:
- 9:使用IX
- 5-8:使用V加若干个I
- 4:使用IV
- 1-3:使用若干个I
python代码
python
class Solution:
def intToRoman(self, num: int) -> str:
"""
使用除法取余法将整数转换为罗马数字
参数:
num: 1-3999范围内的整数
返回:
对应的罗马数字字符串
"""
result = ''
# 处理千位(1000-3000)
# 千位最大到3,直接重复M即可
thousands = num // 1000
result += 'M' * thousands
# 处理百位(100-900)
hundreds = (num % 1000) // 100
if hundreds == 9:
# 900 使用 CM 表示
result += 'CM'
elif hundreds >= 5:
# 500-800 使用 D 加若干个 C 表示
result += 'D' + 'C' * (hundreds - 5)
elif hundreds == 4:
# 400 使用 CD 表示
result += 'CD'
else:
# 100-300 使用若干个 C 表示
result += 'C' * hundreds
# 处理十位(10-90)
tens = (num % 100) // 10
if tens == 9:
# 90 使用 XC 表示
result += 'XC'
elif tens >= 5:
# 50-80 使用 L 加若干个 X 表示
result += 'L' + 'X' * (tens - 5)
elif tens == 4:
# 40 使用 XL 表示
result += 'XL'
else:
# 10-30 使用若干个 X 表示
result += 'X' * tens
# 处理个位(1-9)
ones = num % 10
if ones == 9:
# 9 使用 IX 表示
result += 'IX'
elif ones >= 5:
# 5-8 使用 V 加若干个 I 表示
result += 'V' + 'I' * (ones - 5)
elif ones == 4:
# 4 使用 IV 表示
result += 'IV'
else:
# 1-3 使用若干个 I 表示
result += 'I' * ones
return result
时空复杂度分析
- 时间复杂度分析:O(1):固定的四个位置处理
- 空间复杂度分析:O(1):使用固定大小的空间
2.2 优化解法:模式匹配法
思路
观察罗马数字的规律,发现其遵循特定模式:当较小的罗马数字出现在较大的罗马数字左边时表示减法,右边时表示加法。基于这个规则,我们可以从大到小构建一个模式表,然后通过重复匹配和替换来构建罗马数字。
详细算法步骤:
- 准备模式映射表:
- 包含所有基本数值和特殊组合(如4、9等)
- 按数值从大到小排序
- 每个模式包含数值和对应的罗马数字符号
- 遍历处理过程:
- 从最大的模式开始遍历
- 对每个模式,重复执行:
- 检查当前数字是否大于等于模式值
- 如果是,追加对应的罗马数字符号
- 从输入数字中减去已处理的值
- 直到当前数字小于模式值
- 继续处理下一个模式
- 当数字变为0时可以提前结束
python代码
python
class Solution:
def intToRoman(self, num: int) -> str:
"""
使用模式匹配法将整数转换为罗马数字
参数:
num: 1-3999范围内的整数
返回:
对应的罗马数字字符串
"""
# 定义数值到罗马数字的模式映射
# 按从大到小顺序排列,确保优先匹配大的数值
patterns = [
(1000, "M"), # 1000
(900, "CM"), # 900 = 1000-100
(500, "D"), # 500
(400, "CD"), # 400 = 500-100
(100, "C"), # 100
(90, "XC"), # 90 = 100-10
(50, "L"), # 50
(40, "XL"), # 40 = 50-10
(10, "X"), # 10
(9, "IX"), # 9 = 10-1
(5, "V"), # 5
(4, "IV"), # 4 = 5-1
(1, "I") # 1
]
# 用于存储结果的罗马数字
result = ""
# 遍历所有模式
for value, symbol in patterns:
# 当前数字大于等于模式值时
while num >= value:
# 追加对应的罗马数字符号
result += symbol
# 从输入数字中减去已处理的值
num -= value
# 如果数字已经处理完,提前结束
if num == 0:
break
return result
时空复杂度分析
- 时间复杂度分析:O(1):虽然有循环,但循环次数有上限
- 空间复杂度分析:O(1):使用固定大小的空间
2.3 最优解法:硬编码法
思路
将数字按位分解,每一位(千位、百位、十位、个位)都有固定的几种罗马数字表示方式,提前将这些映射准备好,然后直接查表拼接得到结果。
Python代码
python
class Solution:
def intToRoman(self, num: int) -> str:
"""
将整数转换为罗马数字
参数:
num: 1-3999范围内的整数
返回:
对应的罗马数字字符串
"""
# 千位数字的罗马数字表示(1000, 2000, 3000)
thousands = ["", "M", "MM", "MMM"]
# 百位数字的罗马数字表示(100到900)
hundreds = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"]
# 十位数字的罗马数字表示(10到90)
tens = ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"]
# 个位数字的罗马数字表示(1到9)
ones = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"]
# 分解数字,获取每一位的值
# 例如:1994
# thousand_digit = 1
# hundred_digit = 9
# ten_digit = 9
# one_digit = 4
thousand_digit = num // 1000 # 取千位
hundred_digit = (num % 1000) // 100 # 取百位
ten_digit = (num % 100) // 10 # 取十位
one_digit = num % 10 # 取个位
# 拼接结果
# 直接从对应位置的数组中获取罗马数字表示
# 例如:1994 = M + CM + XC + IV
return thousands[thousand_digit] + hundreds[hundred_digit] + tens[ten_digit] + ones[one_digit]
时空复杂度分析
- 时间复杂度分析:O(1):因为所有操作都是常数时间
- 空间复杂度分析:O(1):使用固定大小的数组存储映射关系
3 题目总结
题目难度:中等
数据类型:整数
应用算法:基于规则