题目
来源:LeetCode.
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字2
写做II
,即为两个并列的1
。12
写做 XII
,即为X + II
。 27
写做 XXVII
, 即为 XX + V + II
。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如4
不写做IIII
,而是IV
。数字1
在数字5
的左边,所表示的数等于大数5
减小数 1
得到的数值4
。同样地,数字9
表示为 IX
。这个特殊的规则只适用于以下六种情况:
I
可以放在V
(5) 和X
(10) 的左边,来表示 4 和 9。X
可以放在L
(50) 和C
(100) 的左边,来表示 40 和 90。C
可以放在D
(500) 和M
(1000) 的左边,来表示 400 和 900。
给你一个整数,将其转为罗马数字。
示例 1:
输入: num = 3
输出: "III"
示例 2:
输入: num = 4
输出: "IV"
示例 3:
输入: num = 9
输出: "IX"
示例 4:
输入: num = 58
输出: "LVIII"
解释: L = 50, V = 5, III = 3.
示例 5:
输入: num = 1994
输出: "MCMXCIV"
解释: M = 1000, CM = 900, XC = 90, IV = 4.
提示:
1 <= num <= 3999
接下来看一下解题思路:
思路:
刚开始看到这道题,想的是用 if - else 写,结果流下了痛苦的眼泪 😮
后来才想到根据罗马数字出现的可能保存到数组然后遍历转换;
首先,罗马数字由 7 个不同的单字母符号组成,而且还有 6 个特殊情况:
{
M
→
1000
C
M
→
900
D
→
500
C
D
→
400
C
→
100
X
C
→
90
L
→
50
X
L
→
40
X
→
10
I
X
→
9
V
→
5
I
V
→
4
I
→
1
\begin{cases} M \ \ \ \rightarrow 1000\\ CM \rightarrow 900\\ D \ \ \ \ \rightarrow 500\\ CD \ \rightarrow 400\\ C \ \ \ \ \rightarrow 100\\ XC \ \rightarrow 90\\ L \ \ \ \ \ \rightarrow 50\\ XL \ \ \rightarrow 40\\ X \ \ \ \ \ \rightarrow 10\\ IX \ \ \ \rightarrow 9\\ V \ \ \ \ \ \rightarrow 5\\ IV \ \ \ \rightarrow 4\\ I \ \ \ \ \ \ \rightarrow 1\\ \end{cases}
⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧M →1000CM→900D →500CD →400C →100XC →90L →50XL →40X →10IX →9V →5IV →4I →1
1、对于转换,需要根据当前数字选择尽可能大的罗马数组,然后减去该值;
然后重复步骤 1 ,直到这个数字为 0 ;
需要给两个数组保存罗马字符和对应的数字;
并且从大到小存储,包装字符和数字一一对应;
public static String intToRoman(int num) {
// 1 <= num <= 3999
if (num < 1 || num > 3999) {
throw new IllegalArgumentException();
}
int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
String[] symbols = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
StringBuffer result = new StringBuffer();
for (int i = 0; i < values.length; ++i) {
while (num >= values[i]) {
num -= values[i];
result.append(symbols[i]);
}
if (num == 0) {
break;
}
}
return result.toString();
}
总结
时间复杂度 O(1),由于
v
a
l
u
e
s
values
values和
S
y
m
b
o
l
s
Symbols
Symbols 长度是固定的,且这 13 字符中的每个字符的出现次数均不会超过 3,因此循环次数有一个确定的上限。对于本题给出的数据范围,循环次数不会超过 15 次;
空间复杂度 O(1);