1 题目描述
2 解题思路
2.1 模拟
通常情况下,罗马数字中小的数字在大的数字的右边。若输入的字符串满足该情况,那么可以将每个字符视作一个单独的值,累加每个字符对应的数值即可。
例如XXVII 可视作 X+X+V+I+I=10+10+5+1+1=27。
若存在小的数字在大的数字的左边的情况,根据规则需要减去小的数字。对于这种情况,我们也可以将每个字符视作一个单独的值,若一个数字右侧的数字比它大,则将该数字的符号取反。
例如XIV 可视作X−I+V=10−1+5=14。
那么我们就从字符串的串头开始遍历,同时我们比较除最后一位以外的其他位与后一位之间的大小。如果当前位罗马数字对应的数字比后一位的小,那么总的数字结果就减去这一位,否则加上这一位。
class Solution:
SYMBOL_VALUES = {
'I': 1,
'V': 5,
'X': 10,
'L': 50,
'C': 100,
'D': 500,
'M': 1000,
}
#每个罗马数字对应的数字
def romanToInt(self, s: str) -> int:
ans = 0
n = len(s)
for i, ch in enumerate(s):
value = Solution.SYMBOL_VALUES[ch]
if i < n - 1 and value < Solution.SYMBOL_VALUES[s[i + 1]]:
#如果当前位比后一位小,那么说明这一位要减掉
ans -= value
else:
ans += value
return ans
2.2 两位两位比较
大致的思路就是,先把所有可能的值都存入一个字典里面
两位罗马数字对应的数字,我们赋值为:两位罗马数字应该的值-两位罗马数字第一位的值
然后我们就累加就可以了
dict.get(a,b):如果找得到a的话,返回a的键值,否则,返回b
这里我们每次都是检索当前位置和他前面一个位置两个元素,拼接起来看在不在字典里面,在的话累加,不在的话,就加上这个位置罗马数字所对应的值。
比如XIV,检索X的时候,返回10;检索XI的时候,因为找不到XI这个两位罗马数字,返回I的值,1,在检索IV的时候,有这个键值对,所以返回IV的3——加上之前I的1,IV的4就计算出来了
class Solution:
def romanToInt(self, s: str) -> int:
dic={'I':1,
'IV':3,
'V':5,
'IX':8,
'X':10,
'XL':30,
'L':50,
'XC':80,
'C':100,
'CD':300,
'D':500,
'CM':800,
'M':1000}
#所有合法的一位&两位罗马数字
number=0;
for i,n in enumerate(s):
number=number+dic.get(s[max(i-1,0):i+1],dic[n])
#如果两位罗马数字存在,那么就返回两位罗马数字(当前位&前一位)对应的数字
#否则,返回当前位罗马数字对应的数字
return(number)