13. 罗马数字转整数

例题:

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

思路:

哈希表

1、匹配字母

创建一个HashMap来存储每个字母对应的值:

  1. 构建一个字典记录所有罗马数字子串,注意长度为 2 的子串记录的值是(实际值 - 子串内左边罗马数字代表的数值)

  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'))

总结

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值