LeetCode 面试经典150题 [18/150 整数转罗马数字]


avatar
GuoYulong 2024-06-20 212

题目描述

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

符号
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. 3000 = MMM 由于 1000 (M) + 1000 (M) + 1000 (M)
  2. 700 = DCC 由于 500 (D) + 100 (C) + 100 (C)
  3. 40 = XL 由于 50 (L) 10 (X)
  4. 9 = IX 由于 10 (X) 1 (I)
  5. 注意:49 不是 50 (L) 1 (I) 因为转换是基于小数位

示例 2:

输入:num = 58

输出:"LVIII"

解释:

复制代码
  1. 50 = L
  2. 8 = VIII

示例 3:

输入:num = 1994

输出:"MCMXCIV"

解释:

复制代码
  1. 1000 = M
  2. 900 = CM
  3. 90 = XC
  4. 4 = IV

个人C++解答

用贪心就可以出来

复制代码
  1. class Solution {
  2. public:
  3. string intToRoman(int num) {
  4. vector<int> value={1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
  5. vector<string> key = { "M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I" };
  6. string str = "";
  7. for (int i=0; i<value.size();i++) {
  8. while(num >= value[i]) {
  9. str.append(key[i]);
  10. num -= value[i];
  11. }
  12. }
  13. return str;
  14. }
  15. };

其他解答

这道题并不难,其实按照罗马数字转整数的思路做就可以,有趣的是,这道题的评论区佬们的做法,请大家欣赏:

官方解答2:硬编码数字

fig3

回顾前言中列出的这 131313 个符号,可以发现:

千位数字只能由 M 表示;
百位数字只能由 C,CD,D 和 CM 表示;
十位数字只能由 X,XL,L 和 XC 表示;
个位数字只能由 I,IV,V 和 IX 表示。
这恰好把这 13 个符号分为四组,且组与组之间没有公共的符号。因此,整数 num 的十进制表示中的每一个数字都是可以单独处理的。

进一步地,我们可以计算出每个数字在每个位上的表示形式,整理成一张硬编码表。如下图所示,其中 0 对应的是空字符串。

fig4

利用模运算和除法运算,我们可以得到 num 每个位上的数字:

复制代码
  1. thousands_digit = num / 1000
  2. hundreds_digit = (num % 1000) / 100
  3. tens_digit = (num % 100) / 10
  4. ones_digit = num % 10

最后,根据 num 每个位上的数字,在硬编码表中查找对应的罗马字符,并将结果拼接在一起,即为 num 对应的罗马数字

复制代码
  1. const string thousands[] = {"", "M", "MM", "MMM"};
  2. const string hundreds[] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
  3. const string tens[] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
  4. const string ones[] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
  5. class Solution {
  6. public:
  7. string intToRoman(int num) {
  8. return thousands[num / 1000] + hundreds[num % 1000 / 100] + tens[num % 100 / 10] + ones[num % 10];
  9. }
  10. };

ID:“抓蚂蚁的小高手” 题解

复制代码
  1. class Solution {
  2. public:
  3. string intToRoman(int num) {
  4. string rome = "IIIVIIIXXXLXXXCCCDCCCMMM";
  5. string ret = "";
  6. int p = 0;
  7. while (num > 0) {
  8. int q = num % 10;
  9. if (q < 4)
  10. ret = rome.substr(p, q) + ret;
  11. else if (q == 4)
  12. ret = rome.substr(p + q - 2, 2) + ret;
  13. else if (q < 9)
  14. ret = rome.substr(p + 3, q - 4) + ret;
  15. else
  16. ret = rome.substr(p + 6, 2) + ret;
  17. num /= 10;
  18. p += 7;
  19. }
  20. return ret;
  21. }
  22. };

ID:“imp” 题解

“ipm”:“最无脑的程序,没有之一,不接受反驳(源程序太长,截取部分)”

复制代码
  1. public String intToRoman(int num) {
  2. String[] arr = new String[]{"","I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII","XIII","XIV","XV","XVI","XVII","XVIII","XIX","XX","XXI","XXII","XXIII","XXIV","XXV","XXVI","XXVII","XXVIII","XXIX","XXX","XXXI","XXXII","XXXIII","XXXIV","XXXV","XXXVI","XXXVII","XXXVIII","XXXIX","XL","XLI","XLII","XLIII","XLIV","XLV","XLVI","XLVII","XLVIII","XLIX","L","LI","LII","LIII","LIV","LV","LVI","LVII","LVIII","LIX","LX","LXI","LXII","LXIII","LXIV","LXV","LXVI","LXVII","LXVIII","LXIX","LXX","LXXI","LXXII","LXXIII","LXXIV","LXXV","LXXVI","LXXVII","LXXVIII","LXXIX","LXXX","LXXXI","LXXXII","LXXXIII","LXXXIV","LXXXV","LXXXVI","LXXXVII","LXXXVIII","LXXXIX","XC","XCI","XCII","XCIII","XCIV","XCV","XCVI","XCVII","XCVIII","XCIX","C","CI","CII","CIII","CIV","CV","CVI","CVII","CVIII","CIX","CX","CXI","CXII","CXIII","CXIV","CXV","CXVI","CXVII","CXVIII","CXIX","CXX","CXXI","CXXII","CXXIII","CXXIV","CXXV","CXXVI","CXXVII","CXXVIII","CXXIX","CXXX","CXXXI","CXXXII","CXXXIII","CXXXIV","CXXXV","CXXXVI"
  3. };
  4. return arr[num];
  5. }

ID:“Yimi” 题解

“Yimi”:“啊我写的好长,思路跟官方的 方法二:硬编码数字 一致”

复制代码
  1. class Solution {
  2. public:
  3. string intToRoman(int num) {
  4. string ans = "";
  5. int M = num / 1000;
  6. num %= 1000;
  7. int C = num / 100;
  8. num %= 100;
  9. int X = num / 10;
  10. num %= 10;
  11. int I = num;
  12. num %= 1;
  13. switch (M) {
  14. case 3:
  15. ans += 'M';
  16. case 2:
  17. ans += 'M';
  18. case 1:
  19. ans += 'M';
  20. case 0:
  21. break;
  22. }
  23. switch (C) {
  24. case 9:
  25. ans += "CM";
  26. break;
  27. case 8:
  28. ans += "DCCC";
  29. break;
  30. case 7:
  31. ans += "DCC";
  32. break;
  33. case 6:
  34. ans += "DC";
  35. break;
  36. case 5:
  37. ans += "D";
  38. break;
  39. case 4:
  40. ans += "CD";
  41. break;
  42. case 3:
  43. ans += 'C';
  44. case 2:
  45. ans += 'C';
  46. case 1:
  47. ans += 'C';
  48. case 0:
  49. break;
  50. }
  51. switch(X) {
  52. case 9:
  53. ans += "XC";
  54. break;
  55. case 8:
  56. ans += "LXXX";
  57. break;
  58. case 7:
  59. ans += "LXX";
  60. break;
  61. case 6:
  62. ans += "LX";
  63. break;
  64. case 5:
  65. ans += "L";
  66. break;
  67. case 4:
  68. ans += "XL";
  69. break;
  70. case 3:
  71. ans += 'X';
  72. case 2:
  73. ans += 'X';
  74. case 1:
  75. ans += 'X';
  76. case 0:
  77. break;
  78. }
  79. switch(I) {
  80. case 9:
  81. ans += "IX";
  82. break;
  83. case 8:
  84. ans += "VIII";
  85. break;
  86. case 7:
  87. ans += "VII";
  88. break;
  89. case 6:
  90. ans += "VI";
  91. break;
  92. case 5:
  93. ans += "V";
  94. break;
  95. case 4:
  96. ans += "IV";
  97. break;
  98. case 3:
  99. ans += 'I';
  100. case 2:
  101. ans += 'I';
  102. case 1:
  103. ans += 'I';
  104. case 0:
  105. break;
  106. }
  107. return ans;
  108. }
  109. };

ID:"Happy Grothendieckcvx"题解

"Happy Grothendieckcvx":用不了一点枚举 没有四千限制也能打

复制代码
  1. string intToRoman(int num) {
  2. map<int,char> roma;
  3. roma.insert(pair<int,char>(6,'M'));
  4. roma.insert(pair<int,char>(5,'D'));
  5. roma.insert(pair<int,char>(4,'C'));
  6. roma.insert(pair<int,char>(3,'L'));
  7. roma.insert(pair<int,char>(2,'X'));
  8. roma.insert(pair<int,char>(1,'V'));
  9. roma.insert(pair<int,char>(0,'I'));
  10. string sorted;
  11. for(int i=4;i>0;i--){
  12. int temp=num%(int)pow(10,i)/(int)pow(10,i-1);
  13. if(temp==9){
  14. sorted+=roma[i*2-2];
  15. sorted+=roma[i*2];
  16. continue;
  17. }
  18. if(temp==4){
  19. sorted+=roma[i*2-2];
  20. sorted+=roma[i*2-1];
  21. continue;
  22. }
  23. if(temp>=5){
  24. sorted+=roma[i*2-1];
  25. temp-=5;
  26. }
  27. for(int j=0;j<temp;j++){
  28. sorted+=roma[i*2-2];
  29. }
  30. }
  31. return sorted;
  32. }

相关阅读

注意!!!

站点域名更新!!!部分文章图片等由于域名问题无法显示!!!

通知!!!

站点域名更新!!!部分文章图片等由于域名问题无法显示!!!