【LeetCode】每日一题:13. 罗马数字转整数

109 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情

13. 罗马数字转整数

罗马数字包含以下七种字符: IVXLCDM

字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 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。 给定一个罗马数字,将其转换成整数。

「示例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. 1 <= s.length <= 15
2. s 仅含字符 ('I', 'V', 'X', 'L', 'C', 'D', 'M')
3. 题目数据保证 s 是一个有效的罗马数字,且表示整数在范围 [1, 3999]4. 题目所给测试用例皆符合罗马数字书写规则,不会出现跨位等情况。
5. ILIM 这样的例子并不符合题目要求,49 应该写作 XLIX999 应该写作 CMXCIX6. 关于罗马数字的详尽书写规则,可以参考 罗马数字 - Mathematics

解题思路

1、首先 先了解罗马数字的计算规律:就是每一位上的字符代表的数字相加。
​
2、其次 什么时候是负数的呢?就是出现IV,IX,XL,XC,XD,XM这6种情况时,前一位字符代表的数字的正负符号是负号,其他情况是正号
​
3、最后 得出罗马字符代表数字的正负号时,就可以将每一位罗马字符代表的数字相加了,其合就是当前罗马字符串代表的阿拉伯数字。

代码实现

/**
 * @param {string} s
 * @return {number}
 */
var romanToInt = function(s) {
    const romanObj = { I:1, V:5, X:10, L:50, C:100, D:500, M:1000 };
    const reg = /^[ivxlcdm]{1,15}$/i;
    const isRomanNum = reg.test(s);
    if(isRomanNum){
        let sum = 0;
        const str = s.toUpperCase();
        const romanNumArr = str.split('');
        for(let j=0;j<romanNumArr.length;j++){
            let nowRoman = romanNumArr[j];//当前位罗马数字
            let nextRoman = romanNumArr[j+1]||'无';//下一位罗马数字
            let nowNum = romanObj[nowRoman];//当前阿拉伯数字
            let nextNum = romanObj[nextRoman]||0;
            if(nextNum>0&&nowNum!=nextNum&&nowNum<nextNum&&(nowRoman=='I'&&['V','X'].includes(nextRoman) || nowRoman=='X'&&['L','C'].includes(nextRoman) || nowRoman=='C'&&['D','M'].includes(nextRoman))){
                nowNum = -romanObj[nowRoman]
            }
            sum += nowNum;
        }
        return sum;
    }
    console.log('请输入正确的罗马数字,且字符长度不超过15位');
};

如果你对这道题目还有疑问的话,可以在评论区进行留言;