例题:
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
思路:
哈希表
1、匹配字母
创建一个HashMap来存储每个字母对应的值:
-
构建一个字典记录所有罗马数字子串,注意长度为
2
的子串记录的值是(实际值 - 子串内左边罗马数字代表的数值) -
这样一来,遍历整个哈希表的时候判断当前位置和前一个位置的两个字符组成的字符串是否在字典内,如果在就记录值,不在就说明当前位置不存在小数字在前面的情况,直接记录当前位置字符对应值
举个例子,遍历经过 IV的时候先记录 I 的对应值 1 再往前移动一步记录 IV的值 3,加起来正好是 IV的真实值 4。max 函数在这里是为了防止遍历第一个字符的时候出现 [−1:0]的情况
链接:https://leetcode.cn/problems/roman-to-integer/solutions/4148/2-xing-python-on-by-knifezhu/
2、减之前的字母的值
I
可以放在V
(5) 和X
(10) 的左边,来表示 4 和 9。X
可以放在L
(50) 和C
(100) 的左边,来表示 40 和 90。C
可以放在D
(500) 和M
(1000) 的左边,来表示 400 和 900。
我们可以了解到通常罗马数字都是小的在大的前面,我们可以匹配当当前i值和i+1的值相比哪个大哪个小,如果小,我们就可以将sum减当前的i值
比如IV=4,I=1,V=5。当匹配到I的时候,我们去看下一个字符的值是否大于当前字符的值,如果大于,我们就减当前的值。5-1=4,所以输出为4。如果不是,那么就sum加上当前的值就可以了。
链接:https://leetcode.cn/problems/roman-to-integer/solutions/87758/qing-xi-tu-jie-python3-by-ml-zimingmeng/
代码
1、匹配字母
def romanToInt(self, s: str) -> int:
n = len(s)
num = 0
for i in range(n):
if s[i] == 'I' and i < n-1 and (s[i+1] == 'V' or s[i+1] == 'X'):
num -= 1
elif s[i] == 'I':
num += 1
elif s[i] == 'V':
num += 5
elif s[i] == 'X' and i < n-1 and (s[i+1] == 'L' or s[i+1] == 'C'):
num -= 10
elif s[i] == 'X':
num += 10
elif s[i] == 'L':
num += 50
elif s[i] == 'C' and i < n-1 and (s[i+1] == 'D' or s[i+1] == 'M'):
num -= 100
elif s[i] == 'C':
num += 100
elif s[i] == 'D':
num += 500
else:
num += 1000
return num
class Solution:
def romanToInt(self, s: str) -> int:
symbol_values = {'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}
result = 0
for i, h in enumerate(s):
str1 = s[max(i-1,0):i+1] #这里不会越界,因为当到最后一个索引的时候,不会再取。
# max是防止第一个字符取到的时候为-1.
# str1是取两个罗马数字的值,i-1,i 为两位数。
if str1 in symbol_values:
result += symbol_values.get(str1) #如果找到两个数字,加上值
else:
result += symbol_values[h] #没有则为普通数字。
return result
2、减之前的字母的值
class Solution:
def romanToInt(self, s: str) -> int:
Roman2Int = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}
Int = 0
n = len(s)
for i in range(n-1): # 这里是n-1是防止遍历到最后再比较i+1,越界。
if Roman2Int[s[i]] < Roman2Int[s[i+1]]:
Int -= Roman2Int[s[i]]
else:
Int += Roman2Int[s[i]]
return Int + Roman2Int[s[-1]] # 如果不是连体数字,就加上最后一个的值,上面是比较,没有加。不加就取不到最后一个字符的值了。
class Solution:
def romanToInt(self, s: str) -> int:
dic = {"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000}
prev = 0
res = 0
for i in reversed(s):
print(i)
now = dic[i] # 将当前元素映射到哈希表中寻值
if now >= prev: 如果现在的元素的值比之前大
res += now
else:
res -= now
prev = now # 将之前的值替换,准备下一个循环
return res
solution = Solution()
print(solution.romanToInt('XIV'))