12. 整数转罗马数字

12. 整数转罗马数字

✨核心逻辑

本题采用 贪心算法 的策略:

  1. 建立映射表:将阿拉伯数字与其对应的罗马数字符号建立一一对应的关系。除了基础的 1000(M)500(D)100(C) 等,必须包含减法规则的组合(如 900(CM)400(CD)90(XC) 等)。
  2. 按值匹配:将数字的映射列表按照数值从大到小的顺序排列。
  3. 循环相减与拼接:遍历映射列表,对于当前的最大数值,只要 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开头的情况存在数组里,少了复杂的代码判断可,思路很巧妙,值得学习

并使用贪心,,一次找最大面额并相减,然后循环直到不再大于为止