编辑
2024-03-05
LeetCode
00
请注意,本文编写于 376 天前,最后修改于 376 天前,其中某些信息可能已经过时。

目录

罗马数字转整数
题解:模拟

罗马数字转整数

罗马数字包含以下七种字符: IVXLCDMI, V, X, L,C,D 和 M

字符数值
II1
VV5
XX10
LL50
CC100
DD500
MM 1000

例如, 罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XIIXII ,即为 X+IIX + II 。 27 写做 XXVIIXXVII, 即为 XX+V+IIXX + V + II

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIIIIIII,而是 IVIV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IXIX。这个特殊的规则只适用于以下六种情况:

II 可以放在 VV (5) 和 XX (10) 的左边,来表示 4 和 9。

XX 可以放在 LL (50) 和 CC (100) 的左边,来表示 40 和 90。

CC 可以放在 DD (500) 和 MM (1000) 的左边,来表示 400 和 900。

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

示例 1:

输入: s = "IIIIII"

输出: 3

示例 2:

输入: s = "IVIV"

输出: 4

示例 3:

输入: s = "IXIX"

输出: 9

示例 4:

输入: s = "LVIIILVIII"

输出: 58

解释: LL = 50, VV= 5, IIIIII = 3.

示例 5:

输入: s = "MCMXCIVMCMXCIV"

输出: 1994

解释: MM = 1000, CMCM = 900, XCXC = 90, IVIV = 4.

提示:

1 <= s.length <= 15

s 仅含字符 (I,V,X,L,C,D,M'I', 'V', 'X', 'L', 'C', 'D', 'M')

题目数据保证 s 是一个有效的罗马数字,且表示整数在范围 [1, 3999] 内

题目所给测试用例皆符合罗马数字书写规则,不会出现跨位等情况。

ILILIMIM这样的例子并不符合题目要求,49 应该写作 XLIXXLIX,999 应该写作 CMXCIXCMXCIX

关于罗马数字的详尽书写规则,可以参考 罗马数字 - Mathematics

罗马数字转整数

c++
class Solution { public: int romanToInt(std::string s) { int num = 0; for (int i = 0; i < s.length(); i++) { switch (s[i]) { case 'I': if (i + 1 < s.length() && s[i + 1] == 'V') { num += 4; i++; } else if (i + 1 < s.length() && s[i + 1] == 'X') { num += 9; i++; } else { num += 1; } break; case 'V': num += 5; break; case 'X': if (i + 1 < s.length() && s[i + 1] == 'L') { num += 40; i++; } else if (i + 1 < s.length() && s[i + 1] == 'C') { num += 90; i++; } else { num += 10; } break; case 'L': num += 50; break; case 'C': if (i + 1 < s.length() && s[i + 1] == 'D') { num += 400; i++; } else if (i + 1 < s.length() && s[i + 1] == 'M') { num += 900; i++; } else { num += 100; } break; case 'D': num += 500; break; case 'M': num += 1000; break; } } return num; } };

题解:模拟

作者:力扣官方题解

链接:https://leetcode.cn/problems/roman-to-integer/solutions/774992/luo-ma-shu-zi-zhuan-zheng-shu-by-leetcod-w55p/

来源:力扣(LeetCode)

思路

通常情况下,罗马数字中小的数字在大的数字的右边。若输入的字符串满足该情况,那么可以将每个字符视作一个单独的值,累加每个字符对应的数值即可。

例如 XXVIIXXVII 可视作 X+X+V+I+I=10+10+5+1+1=27X+X+V+I+I=10+10+5+1+1=27

若存在小的数字在大的数字的左边的情况,根据规则需要减去小的数字。对于这种情况,我们也可以将每个字符视作一个单独的值,若一个数字右侧的数字比它大,则将该数字的符号取反。

例如 XIVXIV 可视作 XI+V=101+5=14X−I+V=10−1+5=14

罗马数字转整数(题解)

c++
class Solution { private: unordered_map<char, int> symbolValues = { {'I', 1}, {'V', 5}, {'X', 10}, {'L', 50}, {'C', 100}, {'D', 500}, {'M', 1000}, }; public: int romanToInt(string s) { int ans = 0; int n = s.length(); for (int i = 0; i < n; ++i) { int value = symbolValues[s[i]]; if (i < n - 1 && value < symbolValues[s[i + 1]]) { ans -= value; } else { ans += value; } } return ans; } };

复杂度分析

时间复杂度:O(n)O(n),其中 nn 是字符串 ss的长度。

空间复杂度:O(1)O(1)

本文作者:古月流新

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!