罗马数字转整数
863 字
4 分钟
罗马数字转整数
题目链接:13. 罗马数字转整数 - 力扣(LeetCode)
- 难度:简单
- 标签:哈希表、数学、字符串
题目描述
Note
罗马数字规则:
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
| 字符 | I | V | X | L | C | D | M |
|---|---|---|---|---|---|---|---|
| 数值 | 1 | 5 | 10 | 50 | 100 | 500 | 1000 |
特殊规则: 通常情况下,小的数字在大的数字右边。若小的数字在大的数字左边,则需减去该小数。
I可以放在V(5) 和X(10) 的左边,来表示 4 和 9。X可以放在L(50) 和C(100) 的左边,来表示 40 和 90。C可以放在D(500) 和M(1000) 的左边,来表示 400 和 900。
示例
- 输入:
s = "MCMXCIV" - 输出:
1994 - 解释:
M = 1000,CM = 900,XC = 90,IV = 4.
方案一:辅助函数映射法
核心思路:
遍历字符串,比较当前字符与下一个字符的值。如果当前字符的值比下一个小,说明触发了“减法”规则(如 IV),此时应从总数中减去当前值;否则,加上当前值。
思考过程与坑点
最初我的代码在处理边界时遇到了问题:
// 典型错误示例:i+1 越界for(int i = 0; i < s.size(); ++i) { int a = valueOf(s[i]); int b = valueOf(s[i+1]); // 当 i 为最后一位时,这里会越界! if(a < b) total += b - a; else total += a;}改进点:
- 使用三目运算符处理最后一个字符的
b值(设为 0)。 - 将
b-a的逻辑简化为:若a < b则total -= a,否则total += a。
完善后的源码
class Solution {public: int valueOf(char c) { switch (c) { case 'I': return 1; case 'V': return 5; case 'X': return 10; case 'L': return 50; case 'C': return 100; case 'D': return 500; case 'M': return 1000; default: return 0; } }
int romanToInt(string s) { int total = 0; for (int i = 0; i < s.size(); ++i) { int a = valueOf(s[i]); // 使用三目运算符安全处理越界 int b = (i + 1 < s.size()) ? valueOf(s[i + 1]) : 0;
if (a < b) { total -= a; // 小数在左,减去 } else { total += a; // 正常情况,加上 } } return total; }};方案二:哈希表法(标准解法)
虽然 switch-case 效率很高,但使用 哈希表(unordered_map) 能够让代码更加简洁且符合现代 C++ 的习惯。
#include <string>#include <unordered_map>
class Solution {public: int romanToInt(std::string s) { // 使用静态常量哈希表,避免重复构造 static const std::unordered_map<char, int> T = { {'I', 1}, {'V', 5}, {'X', 10}, {'L', 50}, {'C', 100}, {'D', 500}, {'M', 1000} };
int total = 0; for (int i = 0; i < (int)s.size(); ++i) { int cur = T.at(s[i]); int nxt = (i + 1 < (int)s.size()) ? T.at(s[i + 1]) : 0;
if (cur < nxt) total -= cur; else total += cur; } return total; }};关键点总结
- 三目运算符:
(i + 1 < s.size()) ? ... : 0是处理数组/字符串越界非常优雅的方式。 - 减法逻辑:罗马数字的减法组合(如
IX)可以拆解为-1 + 10。这比判断两个字符再决定是否跳过一个索引的逻辑要简单得多。 - 时间复杂度:。其中 是字符串的长度。我们只需要遍历一遍字符串。
- 空间复杂度:。
- 方案一:只使用了常数个额外变量。
- 方案二:哈希表的大小取决于字符集的大小,本题字符集固定为 7 个罗马数字,因此也是常数空间。
Tip
罗马数字的规则并不多,理清“左小减、右小加”这条核心逻辑,题目就迎刃而解了。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
最后更新于 2025-09-27,距今已过 214 天
部分内容可能已过时
相关文章 智能推荐
1
回文数
算法 力扣第9题:回文数的判断。从暴力取余到“反转一半”的思路演进,以及字符串双指针解法。
2
最后一个单词的长度
算法 力扣第58题:最后一个单词的长度。从反向遍历的直观思想到双指针的精准定位,掌握字符串处理的边界细节。
3
x 的平方根
算法 力扣第69题:实现 sqrt(x)。深入理解二分查找在数值逼近中的应用,以及避免溢出的数学处理技巧。
4
爬楼梯
算法 力扣第70题:爬楼梯。从递归到动态规划(DP)的演进,深入理解斐波那契数列在算法中的美妙应用。
5
加一
算法 力扣第66题:加一。处理大整数数组的进位逻辑,从逐位检查到首位插入的技巧分析。
随机文章 随机推荐