LeetCode-12-整数转罗马数字

题目

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

符号
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"

解释:

1
2
3
4
5
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"

解释:

1
2
50 = L
8 = VIII

示例 3:

输入:num = 1994

输出:"MCMXCIV"

解释:

1
2
3
4
1000 = M
900 = CM
90 = XC
4 = IV

提示:

  • 1 <= num <= 3999

题解

先说一下大佬的时间、空间很低的代码吧

12. 整数转罗马数字 - 力扣(LeetCode)

其实是罗马数字为了方便交流,肯定还是越短越好,然后因此想到最短的求解方法可以使用贪心算法。

通过分析,除了题目给的数字变换的几个数,还有和49相关的特殊的情况;对与1,直接查表;对于123,是I的叠加;对于4,特殊情况,做减法处理VI;对于5,查表;对于678,大数字在前V,然后是小数字叠加I;对于9,特殊情况,做减法处理IX

贪心的思想是:每次使用当前最大的数字与输入的数字进行比较,得到不超过输入数字的最大数字作为加法因子,然后做差得到新的数,直到最后,就可以得到最短的罗马数字字符串。

这里不需要考虑减法的情况是因为对于49的特殊情况,我们已经当作特例弄出来了,可以直接进行加法计算。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Solution {

public String intToRoman(int num) {
// 把阿拉伯数字与罗马数字可能出现的所有情况和对应关系,放在两个数组中,并且按照阿拉伯数字的大小降序排列
int[] nums = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
String[] romans = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};

StringBuilder stringBuilder = new StringBuilder();
int index = 0;
// 遍历nums数组,千、百、十、个
while (index < 13) {
// 特别注意:这里是等号
while (num >= nums[index]) {
stringBuilder.append(romans[index]);
num -= nums[index];
}
index++;
}
return stringBuilder.toString();
}
}

还是要附上自己写的菜码orz,时间6%+,空间5%+......

思路是很简单的,获取每一位的数字,然后进行判断就好了,需要特殊判断的就是49,然后判断的时候要注意此时判断的数字的位是哪位。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Solution {
public String intToRoman(int num) {
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "I");
map.put(5, "V");
map.put(10, "X");
map.put(50, "L");
map.put(100, "C");
map.put(500, "D");
map.put(1000, "M");

// 首先要获得每一位
int divisor = 10;
String res = "";
while (num > 0) {
// 获得当前位的数字
int temp = num % 10;
if (temp == 4 || temp == 9) {
res += map.get((temp + 1) * divisor / 10) + map.get(1 * divisor / 10);
} else {
// 小于5不等于四,直接补齐
if (temp < 5) {
for (int i = 1; i <= temp; i++) {
res += map.get(1 * divisor / 10);
}
} else {
// 大于5,减去五,再补齐
temp -= 5;
for (int i = 1; i <= temp; i++) {
res += map.get(1 * divisor / 10);
}
res += map.get(5 * divisor / 10);
}
}
num /= 10;
divisor *= 10;
}

return new StringBuffer(res).reverse().toString();

}
}

LeetCode-12-整数转罗马数字
https://excelius.xyz/leetcode-12-整数转罗马数字/
作者
Ther
发布于
2024年6月9日
许可协议