一、题目描述
给定一个整数 num,将其转换为罗马数字。
罗马数字由以下七种字符组成:
| 符号 | 数值 |
|---|---|
| I | 1 |
| V | 5 |
| X | 10 |
| L | 50 |
| C | 100 |
| D | 500 |
| M | 1000 |
特殊规则:
-
4 = IV
-
9 = IX
-
40 = XL
-
90 = XC
-
400 = CD
-
900 = CM
输入范围:
1 <= num <= 3999
示例:
输入:num = 1994
输出:"MCMXCIV"
解释:
1000 = M
900 = CM
90 = XC
4 = IV
二、解题思路(贪心算法)
罗马数字的构造遵循一个从大到小逐步匹配 的规则,因此非常适合使用 贪心算法。
核心思想:
-
预先列出所有可能的罗马数字组合(包括减法规则)
-
按照从大到小的顺序遍历
-
如果当前数值
num >= values[i] -
就拼接对应的罗马字符,并减去该值
-
直到
num变为 0
例如:
num = 1994
匹配过程:
1000 -> M num = 994
900 -> CM num = 94
90 -> XC num = 4
4 -> IV num = 0
最终结果:
MCMXCIV
三、C语言代码实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* intToRoman(int num) {
int values[] = {1000,900,500,400,100,90,50,40,10,9,5,4,1};
char* symbols[] = {
"M","CM","D","CD",
"C","XC","L","XL",
"X","IX","V","IV","I"
};
char* res = (char*)malloc(20 * sizeof(char));
res[0] = '\0';
for(int i = 0; i < 13; i++)
{
while(num >= values[i])
{
strcat(res, symbols[i]);
num -= values[i];
}
}
return res;
}
四、复杂度分析
时间复杂度
O(1)
因为最多只会遍历 13 种罗马符号。
空间复杂度
O(1)
只使用了固定大小的辅助空间。
五、优化思路
上面的代码使用了 strcat() 拼接字符串,但 strcat 每次都需要寻找字符串末尾,效率稍低。
可以通过 维护指针直接写入字符数组 来优化,使代码更加高效。
六、总结
本题核心是:
-
贪心思想
-
预处理罗马数字组合
-
从大到小逐步匹配
关键点:
-
需要包含 6 种特殊减法规则
-
按照 数值从大到小遍历
-
每次减去最大可匹配值
这样即可轻松完成整数到罗马数字的转换。