解决方案:罗马数转为整数

2025-06-10

解决方案:罗马数转为整数

这是 Leetcode 解题系列讲解(索引)的一部分。如果您喜欢这个解法或觉得它有用, 请点赞 此文和/或 在 Leetcode 论坛上为我的解法点赞


Leetcode 问题 #13(简单):罗马数转整数


描述:


跳转至解决方案构想||代码JavaScript | Python | Java | C++

罗马数字由七种不同符号表示I、、、、、VXLCDM

象征 价值
1
5
10
50
100
D 500
1000

例如,用罗马数字2写成II,就是两个一的和。12写成XII,就是X + II。数字27写成XXVII,就是XX + V + II

罗马数字通常从左到右按从大到小的顺序书写。然而,表示四的数字不是IIII。相反,它写成IV。因为“一”在“五”之前,所以我们减去“一”得到“四”。同样的原则也适用于数字“九”,它写成IX。以下六种情况使用了减法:

  • I可以放在V( 5) 和X( 10) 之前,以构成49
  • X可以放在L( 50) 和C( 100) 之前,以构成4090
  • C可以放在D( 500) 和M( 1000) 之前,以构成400900

给定一个罗马数字,将其转换为整数。


例子:

例 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]

主意:


跳转至问题描述||代码JavaScript | Python | Java | C++

用罗马数字计数唯一真正棘手的地方是,当一个数字用作减法而不是加法时。例如,在“IV”中,要从“V”的值5减去“I”的值1。否则,你只是简单地把所有数字的值相加。

关于减法数字,我们应该意识到的一点是,它们之所以容易识别,是因为它们出现在更大的数字之前。这意味着,为了便于识别,更简单的方法是从右到左遍历罗马数字。

那么,这里最简单的做法就是反向迭代S,查找每个字母的值,然后将其添加到我们的答案 ( ans ) 中。如果我们遇到一个字母的值小于迄今为止见过的最大字母值,则应该减去它而不是加上它。

标准方法是使用一个单独的变量来跟踪看到的最大值,但这里有一个更简单的技巧。由于罗马数字记数法中的数字通常从右到左递增,因此任何减法数字也必须小于我们当前的ans

因此,我们可以避免在这里使用额外的变量。我们确实会遇到重复数字导致问题的情况(例如"III" ),但我们可以通过在将numans进行比较之前将其乘以34来解决此问题,因为数字的值会以至少5 倍的增量跳跃。(注意:乘数2太小,因为可能出现一个三重字符后跟另一个字符的情况,例如:"XXXI" ,其中2 * 10 < 21

一旦我们知道如何正确识别减法数字,那么只需向后迭代S查找并返回答案就很简单了


执行:

Javascript 和 Python 都可以非常快速地操作对象/字典,因此我们将使用罗马数字值的查找表。

Java 和 C++ 不能很好地处理对象,因此我们将使用 switch case 来实现相同的功能。


Javascript代码:


跳至问题描述||解决方案

const roman = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}

var romanToInt = function(S) {
    let ans = 0
    for (let i = S.length-1; ~i; i--) {
        let num = roman[S.charAt(i)]
        if (4 * num < ans) ans -= num
        else ans += num
    }
    return ans
};
Enter fullscreen mode Exit fullscreen mode

Python代码:


跳至问题描述||解决方案

roman = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}

class Solution:
    def romanToInt(self, S: str) -> int:
        ans = 0
        for i in range(len(S)-1,-1,-1):
            num = roman[S[i]]
            if 4 * num < ans: ans -= num
            else: ans += num
        return ans
Enter fullscreen mode Exit fullscreen mode

Java代码:


跳至问题描述||解决方案

class Solution {
    public int romanToInt(String S) {
        int ans = 0, num = 0;
        for (int i = S.length()-1; i >= 0; i--) {
            switch(S.charAt(i)) {
                case 'I': num = 1; break;
                case 'V': num = 5; break;
                case 'X': num = 10; break;
                case 'L': num = 50; break;
                case 'C': num = 100; break;
                case 'D': num = 500; break;
                case 'M': num = 1000; break;
            }
            if (4 * num < ans) ans -= num;
            else ans += num;
        }
        return ans;
    }
}
Enter fullscreen mode Exit fullscreen mode

C++代码:


跳至问题描述||解决方案

class Solution {
public:
    int romanToInt(string S) {
        int ans = 0, num = 0;
        for (int i = S.size()-1; ~i; i--) {
            switch(S[i]) {
                case 'I': num = 1; break;
                case 'V': num = 5; break;
                case 'X': num = 10; break;
                case 'L': num = 50; break;
                case 'C': num = 100; break;
                case 'D': num = 500; break;
                case 'M': num = 1000; break;
            }
            if (4 * num < ans) ans -= num;
            else ans += num;
        }
        return ans;        
    }
};
Enter fullscreen mode Exit fullscreen mode
鏂囩珷鏉ユ簮锛�https://dev.to/seanpgallivan/solution-roman-to-integer-567f
PREV
使用 JavaScript 实现简单的 LRU 缓存
NEXT
解决方案:下一个排列