Description
Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
Input: "DCXXI"
Output: 621
Solution
首先我们要知道罗马数字每个数字对应的阿拉伯数字大小,如下表所示
罗马数字 | 阿拉伯数字 |
---|---|
I | 1 |
V | 5 |
X | 10 |
L | 50 |
C | 100 |
D | 500 |
M | 1000 |
然后我们注意到罗马数字的转换有一个特殊的规则,如果有形如 IV
这样的罗马数字,前面的一个 I
符号就让这个数减少了1而不是增加了1
这样的情况就是有对应数字比较小的罗马数字 在 对应数字比较大的罗马数字前面所造成的
其他情况我们直接加上这些罗马数字对应的数值就好了
于是我们可以写出以下代码
Source Code
submission
class Solution {
public:
int romanToInt(string s) {
if (s == "")
return 0;
// 注意空字符串
int result = getInt(s[0]);
int lastNum = getInt(s[0]);
int nextNum = 0;
if (s.length() > 1)
nextNum = getInt(s[1]);
for (int i = 1; i < s.length(); i++)
{
lastNum = getInt(s[i - 1]);
nextNum = getInt(s[i]);
if (lastNum < nextNum)
{
result += nextNum - 2 * lastNum;
// 如果出现形如'IX'情况,要减去两倍的前面的数值,因为之前已经加过一次
}
else
{
result += nextNum;
// 正常情况直接累加
}
}
return result;
}
int getInt(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;
}
return -1;
}
};
Better Solution
参考别人的代码我得知我的算法有以下两点还可以优化:
- 取消函数的调用,使用
Map
等数据结构来优化速度 - 遍历的顺序从后往前,可以减少一次减法
当然最优秀的算法写的十分让人难以看懂,我个人认为在追求更快速度的同时也要注意代码的可读性。