
摘要本文详细解析了 LeetCode 第 12 题「整数转罗马数字」的两种主流解法核心解法硬编码枚举法将整数按千、百、十、个位分解每位数字对应预定义的罗马数字组合最后拼接结果。时间复杂度 O(1)代码直观易懂适合面试场景。贪心算法预先定义所有罗马数字符号及其对应数值从大到小遍历并尽可能使用当前最大符号。同样 O(1) 复杂度代码稍长但更通用。关键要点罗马数字规则7 种基本字符 6 种特殊减法组合IV、IX、XL、XC、CD、CM输入范围限制1-3999罗马数字无 0 表示最大为 MMMCMXCIX两种方法空间复杂度均为 O(1)性能接近硬编码法略优适用场景硬编码法适合初学者和面试贪心算法更易扩展规则变化。文章包含完整的 Java 代码实现、复杂度分析、测试用例及常见问题解答帮助读者全面掌握该题解法。题目描述罗马数字包含以下七种字符IVXLCD和M。字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000罗马数字的规则如下通常情况罗马数字按照从左到右、从大到小的顺序书写表示这些数字相加的和。减法规则有六种特殊情况使用减法表示IV 4 (5-1)IX 9 (10-1)XL 40 (50-10)XC 90 (100-10)CD 400 (500-100)CM 900 (1000-100)题目要求给定一个整数num1 ≤ num ≤ 3999将其转换为罗马数字。解题思路分析方法一硬编码枚举法推荐这是最简单直观的方法。由于罗马数字的表示规则相对固定且题目限制了输入范围1-3999我们可以将每一位数字对应的罗马数字表示预先定义好。核心思路将整数按千位、百位、十位、个位分解每位数字对应一组固定的罗马数字组合将四部分拼接起来优点时间复杂度 O(1)只需要常数次操作代码清晰易懂执行效率高方法二贪心算法另一种常见解法是使用贪心策略预先定义所有可能的罗马数字符号及其对应的数值从大到小遍历这些符号每次尽可能使用当前最大的符号这种方法同样高效但代码稍长一些。代码实现方法一硬编码枚举法classSolution{publicStringintToRoman(intnum){// 分解数字的每一位intanum%10;// 个位num/10;intbnum%10;// 十位num/10;intcnum%10;// 百位num/10;intdnum%10;// 千位// 拼接结果returnnum4(d)num3(c)num2(b)num1(a);}// 处理千位 (1000-3000)privateStringnum4(intn){switch(n){case1:returnM;case2:returnMM;case3:returnMMM;default:return;}}// 处理百位 (100-900)privateStringnum3(intn){switch(n){case1:returnC;case2:returnCC;case3:returnCCC;case4:returnCD;case5:returnD;case6:returnDC;case7:returnDCC;case8:returnDCCC;case9:returnCM;default:return;}}// 处理十位 (10-90)privateStringnum2(intn){switch(n){case1:returnX;case2:returnXX;case3:returnXXX;case4:returnXL;case5:returnL;case6:returnLX;case7:returnLXX;case8:returnLXXX;case9:returnXC;default:return;}}// 处理个位 (1-9)privateStringnum1(intn){switch(n){case1:returnI;case2:returnII;case3:returnIII;case4:returnIV;case5:returnV;case6:returnVI;case7:returnVII;case8:returnVIII;case9:returnIX;default:return;}}}方法二贪心算法备选classSolution{publicStringintToRoman(intnum){int[]values{1000,900,500,400,100,90,50,40,10,9,5,4,1};String[]symbols{M,CM,D,CD,C,XC,L,XL,X,IX,V,IV,I};StringBuilderromannewStringBuilder();for(inti0;ivalues.lengthnum0;i){while(numvalues[i]){num-values[i];roman.append(symbols[i]);}}returnroman.toString();}}复杂度分析时间复杂度方法一O(1)。无论输入数字多大都只需要进行固定次数的操作分解数字 4次switch判断。方法二O(1)。最多循环13次values数组长度也是常数时间复杂度。空间复杂度两种方法都是 O(1)只使用了常数级别的额外空间。测试用例publicclassTest{publicstaticvoidmain(String[]args){SolutionsolutionnewSolution();// 测试用例System.out.println(3 - solution.intToRoman(3));// IIISystem.out.println(4 - solution.intToRoman(4));// IVSystem.out.println(9 - solution.intToRoman(9));// IXSystem.out.println(58 - solution.intToRoman(58));// LVIIISystem.out.println(1994 - solution.intToRoman(1994));// MCMXCIVSystem.out.println(3999 - solution.intToRoman(3999));// MMMCMXCIX}}常见问题解答Q1: 为什么输入范围是 1-3999A: 罗马数字没有表示 0 的符号且最大的常规罗马数字是 MMM(3000) CM(900) XC(90) IX(9) 3999。Q2: 两种方法哪种更好A: 硬编码枚举法更直观易懂适合面试和初学者理解。贪心算法更通用如果规则变化更容易扩展。在实际编码中硬编码法因为减少了循环性能略优。Q3: 如何处理边界情况A: 题目保证输入在有效范围内但实际开发中可以添加输入验证if(num1||num3999){thrownewIllegalArgumentException(输入数字必须在 1-3999 范围内);}总结LeetCode 12题整数转罗马数字是一道经典的字符串处理题目主要考察对罗马数字规则的理解数字的分解与组合能力代码的清晰度和可读性硬编码枚举法虽然看起来简单粗暴但在这道题中是最优解之一。它充分利用了题目限制1-3999将问题分解为四个独立的子问题代码既高效又易于理解。关键点理解罗马数字的构成规则特别是6种特殊的减法情况IV, IX, XL, XC, CD, CM这是解题的核心。希望这篇题解对你有帮助如果有任何疑问或建议欢迎在评论区留言讨论。