Offer 驾到,掘友接招!我正在参与 2022 春招打卡活动,点击查看活动详情。
一、题目描述:
- 整数转罗马数字-难度中等
罗马数字包含以下七种字符: 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
二、题目和思路分析:
由题意可知
1写作I
2写作II
3写作III
4写作IV
5写作V
6写作VI
7写作VII
8写作VIII
9写作IX
10写作X
11写作XI
12写作XII
13写作XIII
14写作XIV
......
那么按着自己思路转换的话,是怎样的呢?如:2888
首先我们写2000是1000+1000,即MM
800是500+300,即DCCC
80是加50+30,即LXXX
8是加5+3,即VIII
结果就是拼接起来的MMDCCCLXXXVIII?
好长啊。。。
可以看出:不满10的以5为基准决定增减,减的话放在5左边,加的话放在5右边,按照这个标准,能列出基准值1-3000的基准值
1写作I 10写作X 100写作C 1000写作M
2写作II 20写作XX 200写作CC 2000写作MM
3写作III 30写作XXX 300写作CCC 3000写作MMM
4写作IV 40写作XL 400写作CD
5写作V 50写作L 500写作D
6写作VI 60写作LX 600写作DC
7写作VII 70写作LXX 700写作DCC
8写作VIII 80写作LXXX 800写作DCCC
9写作IX 90写作XC 900写作CM
既然结果是拼接的,又有基准值,那么很容易就能写出我想要的代码了:
三、代码:
代码实现如下:
/**
* @param {number} num
* @return {string}
*/
var intToRoman = function(num) {
let obj = {
4: ['M', 'MM', 'MMM'],
3: ['C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'],
2: ['X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'],
1: ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX']
}
let arr = [...num.toString()].reverse() // 翻转后直接从个位数开始拼接即可
let res = ''
arr.forEach((item, index)=>{
if(+item>0){ // 如果当前数字不为0,为0时生效的应该是翻转后的后一位数字,如10,取的是十位数,个位数不取
res = obj[index+1][+item-1] + res // 取出当前数字对应的罗马数字,然后将得到的值拼接在结果的前面
}
})
return res
}
四、总结:
这道题难度还可以,按着思路,把思路转化为代码即可。
第一次提交因为忘记判断数字中0的情况,导致解答错误,第二次提交则是因为obj对象中的初始值粗心写错了。
还需要再细心一点点,再对逻辑的检查仔细一点点。
加油吧!