LeetCode整数转罗马数字

题目描述

七个不同的符号代表罗马数字,其值如下:

符号
I1
V5
X10
L50
C100
D500
M1000

罗马数字是通过添加从最高到最低的小数位值的转换而形成的。将小数位值转换为罗马数字有以下规则:

  • 如果该值不是以 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

但当罗马数字进位值(个、十、百、千)为 94 时,数字组成变为:小的数字+大的数字

例如:

罗马数字阿拉伯数字
IV4
IX9
XL40
XC90
CD400
CM900
  • 由上述可以推出罗马数字每个进位值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];
};

代码分析

  1. 首先,定义了四个数组 QBSG,分别代表千位、百位、十位和个位的罗马数字表示。每个数组都包含了从0到9的罗马数字表示,这些表示遵循了罗马数字的规则,包括减法形式(例如 IVIX 等)。

  2. 函数 intToRoman 接受一个参数 num,这个参数是要转换的整数。

  3. 使用 Math.floor(num/1000) 计算 num 除以1000的商,这将给出千位上的罗马数字数量。然后通过 Q 数组索引这个数量,得到千位上的罗马数字表示。

  4. 使用 (num%1000)/100 计算 num 除以1000的余数再除以100,这将给出百位上的罗马数字数量。然后通过 B 数组索引这个数量,得到百位上的罗马数字表示。

  5. 使用 (num%100)/10 计算 num 除以100的余数再除以10,这将给出十位上的罗马数字数量。然后通过 S 数组索引这个数量,得到十位上的罗马数字表示。

  6. 使用 num%10 计算 num 除以10的余数,这将给出个位上的罗马数字数量。然后通过 G 数组索引这个数量,得到个位上的罗马数字表示。

  7. 最后,将千位、百位、十位和个位的罗马数字表示拼接起来,形成最终的罗马数字字符串,并返回这个字符串。

这个函数的实现是高效的,因为它避免了递归和复杂的条件判断,而是直接使用数组索引来获取每个位数的罗马数字表示。时间复杂度为 O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值