13. Roman to Integer
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, 2 is written as II in Roman numeral, just two ones added together. 12 is written as XII, which is simply X + II. The number 27 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 before V (5) and X (10) to make 4 and 9.
X can be placed before L (50) and C (100) to make 40 and 90.
C can be placed before D (500) and M (1000) to make 400 and 900.
Given a roman numeral, convert it to an integer.
Example 1:
Input: s = “III”
Output: 3
Explanation: III = 3.
Example 2:
Input: s = “LVIII”
Output: 58
Explanation: L = 50, V= 5, III = 3.
Example 3:
Input: s = “MCMXCIV”
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
Constraints:
1 <= s.length <= 15
s contains only the characters (‘I’, ‘V’, ‘X’, ‘L’, ‘C’, ‘D’, ‘M’).
It is guaranteed that s is a valid roman numeral in the range [1, 3999].
hint1
Problem is simpler to solve by working the string from back to front and using a map.
solution1 模拟
思路
通常情况下,罗马数字中小的数字在大的数字的右边。若输入的字符串满足该情况,那么可以将每个字符视作一个单独的值,累加每个字符对应的数值即可。
例如 \texttt{XXVII}XXVII 可视作 \texttt{X}+\texttt{X}+\texttt{V}+\texttt{I}+\texttt{I}=10+10+5+1+1=27X+X+V+I+I=10+10+5+1+1=27。
若存在小的数字在大的数字的左边的情况,根据规则需要减去小的数字。对于这种情况,我们也可以将每个字符视作一个单独的值,若一个数字右侧的数字比它大,则将该数字的符号取反。
例如 \texttt{XIV}XIV 可视作 \texttt{X}-\texttt{I}+\texttt{V}=10-1+5=14X−I+V=10−1+5=14。
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)。
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/roman-to-integer/solution/luo-ma-shu-zi-zhuan-zheng-shu-by-leetcod-w55p/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
//通常情况下,罗马数字中小的数字在大的数字的右边
//I, V, X, L,C,D 和 M。
int romanToInt(string s) {
//建立映射关系
unordered_map<char,int> hash = {{'I',1},{'V', 5},{'X', 10},{'L', 50},{'C', 100},{'D', 500},{'M', 1000}};
//如果只有一个元素,直接返回对应值
if(s.size()==1) return hash[s[0]];
int sum = 0; //保存结果
int i=0;
for(;i<s.size()-1;i++){
//如果当前字符比它后面的字符要大,说明不是特例
if(hash[s[i]]>=hash[s[i+1]]){
sum+=hash[s[i]]; //保存结果
}
//如果当前字符比它后面的字符小,说明是特例
else{
sum+=hash[s[i+1]]-hash[s[i]]; //用大的减去小的
i++; //i先往后移动一位,再通过for循环往后移动,相当于移动两位
}
}
//此时i指向最后一个字符s[s.size()-1]
if(hash[s[i-1]]>=hash[s[i]]) sum+=hash[s[i]]; //如果是正常的,加上去即可
//如果是特例,不用管了
return sum;
}
};
作者:traveller-lzx
链接:https://leetcode.cn/problems/roman-to-integer/solution/c-luo-ma-shu-zi-zhuan-zheng-shu-by-trave-0xb5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。