12. 整数转罗马数字
✨核心逻辑
本题采用 贪心算法 的策略:
- 建立映射表:将阿拉伯数字与其对应的罗马数字符号建立一一对应的关系。除了基础的
1000(M)、500(D)、100(C)等,必须包含减法规则的组合(如900(CM)、400(CD)、90(XC)等)。 - 按值匹配:将数字的映射列表按照数值从大到小的顺序排列。
- 循环相减与拼接:遍历映射列表,对于当前的最大数值,只要
num还大于或等于它,就将该数值减去,并在结果字符串中拼接上对应的罗马数字符号。直到该数值无法再被减去,再转向下一个较小的数值。
🔥代码实现(含详细变量注释)
class Solution {
public String intToRoman(int num) {
// values:按照从大到小顺序排列的、需要映射的阿拉伯数值
// 包含基础值和减法规则的特殊组合(如 900, 400, 90 等)
int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
// symbols:与 values 数组一一对应罗马数字字符(字符串)
String[] symbols = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
// sb:用于动态拼接和构建最终罗马数字结果的 StringBuilder
StringBuilder sb = new StringBuilder();
// i:遍历 values 和 symbols 数组的索引,确保按从大到小的顺序进行贪心匹配
for (int i = 0; i < values.length; i++) {
// while 循环:只要当前的 num 还大于等于当前数值 values[i]
// 就说明还能减去该部分值并拼接到结果中
while (num >= values[i]) {
num -= values[i]; // 减去对应的数值
sb.append(symbols[i]); // 将对应的罗马数字符号拼接到 StringBuilder 中
}
}
// 循环处理完毕后,将 StringBuilder 转换为字符串并返回
return sb.toString();
}
}
- ⏱️复杂度分析
时间复杂度:O(1)。虽然内部包含 while 循环,但由于罗马数字的表示受限于固定的数值集合,最大的整数(如 3999)也只会执行有限次数的减法操作(理论上不超过 15 次),与输入的规模无关。
空间复杂度:O(1)。使用了两个固定长度为 13 的数组 values 和 symbols,以及一个结果字符串生成器 sb,占用空间基本恒定,不随输入规模 num 的增加而显著增长。
🔍总结一下:
直接把4,9开头的情况存在数组里,少了复杂的代码判断可,思路很巧妙,值得学习
并使用贪心,,一次找最大面额并相减,然后循环直到不再大于为止