LeetCode整数转罗马数字
题目描述
七个不同的符号代表罗马数字,其值如下:
符号 | 值 |
---|---|
I | 1 |
V | 5 |
X | 10 |
L | 50 |
C | 100 |
D | 500 |
M | 1000 |
罗马数字是通过添加从最高到最低的小数位值的转换而形成的。将小数位值转换为罗马数字有以下规则:
- 如果该值不是以 4 或 9 开头,请选择可以从输入中减去的最大值的符号,将该符号附加到结果,减去其值,然后将其余部分转换为罗马数字。
- 如果该值以 4 或 9 开头,使用 减法形式,表示从以下符号中减去一个符号,例如 4 是 5 (
V
) 减 1 (I
):IV
,9 是10 (X
) 减 1 (I
):IX
。仅使用以下减法形式:4 (IV
),9 (IX
),40 (XL
),90 (XC
),400 (CD
) 和 900 (CM
)。 - 只有 10 的次方(
I, X, C, M
)最多可以连续附加 3 次以代表 10 的倍数。你不能多次附加 5 (V
),50 (L
) 或 500 (D
)。如果需要将符号附加4次,请使用 减法形式。
给定一个整数,将其转换为罗马数字。
示例 1:
输入:num = 3749
输出: "MMMDCCXLIX"
解释:
3000 = MMM 由于 1000 (M) + 1000 (M) + 1000 (M)
700 = DCC 由于 500 (D) +100 (C) + 100 (C)
40 = XL 由于 50 (L) 减 10 (X)
9 = IX 由于 10 (X) 减 1(I)
注意:49 不是 50 (L) 减 1 (I) 因为转换是基于小数位
示例 2:
输入:num = 58
输出:"LVIII"
解释:
50 = L
8 = VIII
示例 3:
输入:num = 1994
输出:"MCMXCIV"
解释:
1000 = M
900 = CM
90 = XC
4 = IV
解题思路
已知:罗马数字包含以下七种字符:I,V,X,L,C,D,M
//转换表为:
字符 数值 进位
I 1 个位值为1
V 5 个位值为5
X 10 十位值为1
L 50 十位值为5
C 100 百位值为1
D 500 百位值为5
M 1000 千位值为1
由罗马数字表示规则可知
一般情况下 数字组成:大的数字位+小的数字位
- 例如:
6:VI 7:VII 8:VIII
- 可知:数值大小 == 大的数字位+小的数字位
- 再如:
1:I 2:II 3: III
但当罗马数字进位值(个、十、百、千)为 9
或 4
时,数字组成变为:小的数字+大的数字
例如:
罗马数字 | 阿拉伯数字 |
---|---|
IV | 4 |
IX | 9 |
XL | 40 |
XC | 90 |
CD | 400 |
CM | 900 |
- 由上述可以推出罗马数字每个进位值1-9的表示法:
- 个位【1-9】:
I、II、III、IV、V、VI、VII、VIII、IX
(对应阿拉伯数字X%10
) - 十位【1-9】:
X、XX、XXX、XL、L、LX、LXX、LXXX、XC
(对应阿拉伯数字(X%100)/10
) - 百位【1-9】:
C、CC、CCC、CD、D、DC、DCC、DCCC、CM
(对应阿拉伯数字(X%1000)/100
) - 千位【1-9】:
M、MM、MMM
(对应阿拉伯数字X/1000
) - 由以上可知一个阿拉伯数字 => 罗马数字
num => num/1000 + (num%1000)/100 +(num%100)/10 + num%10
代码
/**
* @param {number} num
* @return {string}
*/
var intToRoman = function(num) {
var Q = ["", "M", "MM", "MMM"];
var B = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"];
var S = ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"];
var G = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"];
return Q[Math.floor(num/1000)] + B[Math.floor((num%1000)/100)] + S[Math.floor((num%100)/10)] + G[num%10];
};
代码分析
-
首先,定义了四个数组
Q
、B
、S
和G
,分别代表千位、百位、十位和个位的罗马数字表示。每个数组都包含了从0到9的罗马数字表示,这些表示遵循了罗马数字的规则,包括减法形式(例如IV
、IX
等)。 -
函数
intToRoman
接受一个参数num
,这个参数是要转换的整数。 -
使用
Math.floor(num/1000)
计算num
除以1000的商,这将给出千位上的罗马数字数量。然后通过Q
数组索引这个数量,得到千位上的罗马数字表示。 -
使用
(num%1000)/100
计算num
除以1000的余数再除以100,这将给出百位上的罗马数字数量。然后通过B
数组索引这个数量,得到百位上的罗马数字表示。 -
使用
(num%100)/10
计算num
除以100的余数再除以10,这将给出十位上的罗马数字数量。然后通过S
数组索引这个数量,得到十位上的罗马数字表示。 -
使用
num%10
计算num
除以10的余数,这将给出个位上的罗马数字数量。然后通过G
数组索引这个数量,得到个位上的罗马数字表示。 -
最后,将千位、百位、十位和个位的罗马数字表示拼接起来,形成最终的罗马数字字符串,并返回这个字符串。
这个函数的实现是高效的,因为它避免了递归和复杂的条件判断,而是直接使用数组索引来获取每个位数的罗马数字表示。时间复杂度为 O(1)