2019.1.12
题目描述:
Roman numerals are represented by seven different symbols: I
, V
, X
, L
, C
, D
and M
.
Symbol Value I 1 V 5 X 10 L 50 C 100 D 500 M 1000
For example, two is written as II
in Roman numeral, just two one's added together. Twelve is written as, XII
, which is simply X
+ II
. The number twenty seven is written as XXVII
, which is XX
+ V
+ II
.
Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII
. Instead, the number four is written as IV
. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX
. There are six instances where subtraction is used:
I
can be placed beforeV
(5) andX
(10) to make 4 and 9.X
can be placed beforeL
(50) andC
(100) to make 40 and 90.C
can be placed beforeD
(500) andM
(1000) to make 400 and 900.
Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999.
Example 1:
Input: "III" Output: 3
Example 2:
Input: "IV" Output: 4
Example 3:
Input: "IX" Output: 9
Example 4:
Input: "LVIII" Output: 58 Explanation: L = 50, V= 5, III = 3.
Example 5:
Input: "MCMXCIV" Output: 1994 Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
将罗马数字转换成数字
这题我半个多小时没有头绪。。。最后只好搜了一下相关博客,看完才顿悟,其实理解了转换规律之后就非常简单了。
首先用一个map数据结构,将罗马数字的字符转化为对应的数值。
因为输入的一定是罗马字符,那么我们只要考虑两种情况即可:
第一,如果当前字符是最后一个字符,或者不小于右边的字符的话,则加上当前字符。
第二,其他情况则减去这个字符。
比如说"MCMXCIV",第一个是M,代表1000,第二个是C,代表100,第三个是M,代表1000,用以上两条规律,可以知道,第一个字母M大于第二个字母C,所以是加上1000,第二个C小于第三个字母M,所以要减去100,依次类推,可以最终转换为数字。
这题简直了。。。就是看你看不看得懂转换规律。。汗颜。。+_+。。
解法一:
class Solution {
public:
int romanToInt(string s) {
int res = 0; //记录转换后的数字
unordered_map<char, int> m{{'I', 1}, {'V', 5}, {'X', 10}, {'L', 50}, {'C', 100}, {'D', 500}, {'M', 1000}}; //用HashMap映射符号和数值
for (int i = 0; i < s.size(); ++i) {
int val = m[s[i]]; //用临时变量暂存当前符号的数值
if (i == s.size() - 1 || m[s[i+1]] <= m[s[i]])
res += val; //如果当前是最后一个字符或者当前字符数值大于等于后面一位字符的数值,就加上当前值
else res -= val; //反之就减去当前值
}
return res;
}
};
执行用时86ms
解法二:
提交之后看了一下执行用时较少的,居然是一路if下去。。很暴力
class Solution {
public:
int romanToInt(string s) {
int total = 0;
for(int i=0; i<s.size(); i++)
{
if(s[i] == 'I')
{
total++;
}
else if(s[i] == 'V' && i > 0 && s[i-1] == 'I')
{
total += 3;
}
else if(s[i] == 'V' && s[i-1] != 'I')
{
total += 5;
}
else if(s[i] == 'X' && i > 0 && s[i-1] == 'I')
{
total += 8;
}
else if(s[i] == 'X' && s[i-1] != 'I')
{
total += 10;
}
else if(s[i] == 'L' && i > 0 && s[i-1] == 'X')
{
total += 30;
}
else if(s[i] == 'L' && s[i-1] != 'X')
{
total += 50;
}
else if(s[i] == 'C' && i > 0 && s[i-1] == 'X')
{
total += 80;
}
else if(s[i] == 'C' && s[i-1] != 'X')
{
total += 100;
}
else if(s[i] == 'D' && i > 0 && s[i-1] == 'C')
{
total += 300;
}
else if(s[i] == 'D' && s[i-1] != 'C')
{
total += 500;
}
else if(s[i] == 'M' && i > 0 && s[i-1] == 'C')
{
total += 800;
}
else if(s[i] == 'M' && s[i-1] != 'C')
{
total += 1000;
}
}
return total;
}
};
这个真是太狠了。