1:问题描述
来源:LeetCode
难度:简单
问题详情:
罗马数字包含以下七种字符: I
, V
, X
, L
,C
,D
和 M
。
字符 | 数值 |
---|---|
I I I | 1 |
V V V | 5 |
X X X | 10 |
L L L | 50 |
C C C | 100 |
D D D | 500 |
M M M | 1000 |
例如, 罗马数字 2
写做 II
,即为两个并列的 1
。12
写做 XII
,即为 X + II
。 27
写做 XXVII
, 即为 XX + V + II
。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4
不写做 IIII
,而是 IV
。数字 1
在数字 5
的左边,所表示的数等于大数 5
减小数 1
得到的数值 4
。同样地,数字 9
表示为 IX
。这个特殊的规则只适用于以下六种情况:
- I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
- X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
- C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。(注意与第12题的区分)
示例 1:
输入: s = “III”
输出: 3
示例 2:
输入: s = “IV”
输出: 4
示例 3:
输入: s = “IX”
输出: 9
示例 4:
输入: s = “LVIII”
输出: 58
解释: L = 50, V= 5, III = 3.
示例 5:
输入: s = “MCMXCIV”
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.
提示:
- 1 <= s.length <= 15
- s 仅含字符 (‘I’, ‘V’, ‘X’, ‘L’, ‘C’, ‘D’, ‘M’)
- 题目数据保证 s 是一个有效的罗马数字,且表示整数在范围 [1, 3999] 内
- 题目所给测试用例皆符合罗马数字书写规则,不会出现跨位等情况。IL 和 IM 这样的例子并不符合题目要求,49 应该写作 XLIX,999 应该写作 CMXCIX 。
2:问题分析
2.1 时间复杂度和空间复杂度
在真正开始介绍各种算法前,先以表格形式展示各自的时间复杂度和空间复杂度,其中 n n n表示字符串 s s s的长度。
算法 | 时间复杂度 | 空间复杂度 |
---|---|---|
模拟1 | O ( n ) O(n) O(n) | O ( 1 ) O(1) O(1) |
模拟2 | O ( n ) O(n) O(n) | O ( 1 ) O(1) O(1) |
2.2 模拟1
图片来源。
受到上一题的启发,我们同样构建如上图所示的键值对。
然后尝试搜索给定的罗马字符中的连续两个字符所对应的数值,如果找不到,则搜索单个字符对应的数值。
2.2.1 代码
def romanToInt(s: str) -> int:
trans_dict = {
'M': 1000,
'CM': 900,
'D': 500,
'CD': 400,
'C': 100,
'XC': 90,
'L': 50,
'XL': 40,
'X': 10,
'IX': 9,
'V': 5,
'IV': 4,
'I': 1
}
i = 0
result = 0
while i < len(s):
ans = 0
if i + 1 < len(s):
ans = trans_dict.get(s[i:i + 2], 0)
if ans == 0:
ans = trans_dict.get(s[i], 0)
i += 1
else:
i += 2
result += ans
return result
时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( 1 ) O(1) O(1)
2.3 模拟2
可以从罗马数字的构造原理上出发,当左边字符的数值小于右边字符的数值时,说明这两个字符构成了特殊情况。比如IX
,I<X
,表示的是-I+X
.
否则为非特殊情况,只需找到当前字符对应的数值即可。
2.3.1 代码
代码如下:
def romanToInt2(s: str) -> int:
trans_dict = {
'M': 1000,
'D': 500,
'C': 100,
'L': 50,
'X': 10,
'V': 5,
'I': 1
}
i = 0
result = 0
while i < len(s):
if i + 1 < len(s) and trans_dict[s[i]] < trans_dict[s[i + 1]]:
result -= trans_dict[s[i]]
else:
result += trans_dict[s[i]]
i += 1
return result
时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( 1 ) O(1) O(1)