LeetCode--整数转罗马数字

电玩女神 2022-03-06 15:26 328阅读 0赞

题干:

罗马数字包含以下七种字符: IVXLCDM

  1. 字符 数值
  2. I 1
  3. V 5
  4. X 10
  5. L 50
  6. C 100
  7. D 500
  8. M 1000

例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

  • I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
  • X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
  • C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。

示例 1:

  1. 输入: 3
  2. 输出: "III"

示例 2:

  1. 输入: 4
  2. 输出: "IV"

示例 3:

  1. 输入: 9
  2. 输出: "IX"

示例 4:

  1. 输入: 58
  2. 输出: "LVIII"
  3. 解释: L = 50, V = 5, III = 3.

示例 5:

  1. 输入: 1994
  2. 输出: "MCMXCIV"
  3. 解释: M = 1000, CM = 900, XC = 90, IV = 4.

解答一(思路):

1、先用map集合将罗马数字标识与整数对应值一一存储起来。

2、再从高位到低位(千位~个位)依次将整数转换罗马。

3、考虑边界和特殊数字(4和9)的转换.

优点:能详细依次计算出每个位上的转换,扩展后算法任然可用。

缺点:太繁杂,线性时间复杂度高,空间耗用较大。

  1. class Solution {
  2. public String intToRoman(int num) {
  3. String result = "";
  4. if(num <1 || num >3999){
  5. return result;
  6. }
  7. Map<Integer,String> dataMap = new HashMap<Integer,String>();
  8. dataMap.put(1,"I");
  9. dataMap.put(5,"V");
  10. dataMap.put(10,"X");
  11. dataMap.put(50,"L");
  12. dataMap.put(100,"C");
  13. dataMap.put(500,"D");
  14. dataMap.put(1000,"M");
  15. int g = num%10; //个位
  16. int sw = num/10%10; //十位
  17. int b = num/100%10; //百位
  18. int q = num/1000%10; //千位
  19. //千位
  20. if(q >0){
  21. for(int i=1;i<=q;i++){
  22. result += dataMap.get(1000);
  23. }
  24. }
  25. //百位
  26. if(b >0 ){
  27. if(b == 4){
  28. result += dataMap.get(100);
  29. result += dataMap.get(500);
  30. }else if(b < 4){
  31. for(int i =1;i<=b;i++){
  32. result += dataMap.get(100);
  33. }
  34. }else if(9>b && b>4){
  35. String tmp = dataMap.get(500);
  36. for(int j=6;j<=b;j++){
  37. tmp += dataMap.get(100);
  38. }
  39. result += tmp;
  40. }else if(b ==9){
  41. result += dataMap.get(100);
  42. result += dataMap.get(1000);
  43. }
  44. }
  45. //十位
  46. if(sw >0){
  47. if(sw == 4){
  48. result += dataMap.get(10);
  49. result += dataMap.get(50);
  50. }else if(sw <4){
  51. for(int i=1;i<=sw;i++){
  52. result += dataMap.get(10);
  53. }
  54. }else if(sw<9 && sw>4){
  55. String tmp = dataMap.get(50);
  56. for(int j=6;j<=sw;j++){
  57. tmp += dataMap.get(10);
  58. }
  59. result += tmp;
  60. }else if(sw ==9){
  61. result += dataMap.get(10);
  62. result += dataMap.get(100);
  63. }
  64. }
  65. //个位
  66. if(g > 0){
  67. if(g == 4){
  68. result += dataMap.get(1);
  69. result += dataMap.get(5);
  70. }else if(g<4){
  71. for(int i=1;i<=g;i++){
  72. result += dataMap.get(1);
  73. }
  74. }else if(g<9 && g>4){
  75. String tmp = dataMap.get(5);
  76. for(int j=6;j<=g;j++){
  77. tmp += dataMap.get(1);
  78. }
  79. result += tmp;
  80. }else if(g ==9){
  81. result += dataMap.get(1);
  82. result += dataMap.get(10);
  83. }
  84. }
  85. return result;
  86. }
  87. }

解答二(思路):

1、将所有特殊整点位数的罗马数字和整数,分别用字符串数组和int数组初始化(从大至小)。

2、循环并比较整数int数组与输入需转换目标整数的大小,如果目标>=int[i]则依次减掉目标大于int数组的值,结果字符串拼接对应罗马数字。

优点:线性时间和空间复杂度较低,简洁易读;算法较优。

缺点:如果目标数字过大,并且罗马数字表示负责的话,加大了初始化整数数组和罗马字符数组工作,并易遗漏。

  1. class Solution {
  2. public String intToRoman(int num) {
  3. int values[]={1000,900,500,400,100,90,50,40,10,9,5,4,1};
  4. String reps[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
  5. StringBuffer sb=new StringBuffer();
  6. for(int i=0; i<13; i++){
  7. while(num>=values[i]){
  8. num -= values[i];
  9. sb.append(reps[i]);
  10. }
  11. }
  12. return sb.toString();
  13. }
  14. }

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvbGxvd18yNA_size_16_color_FFFFFF_t_70关注公众号:nick_coding1024

觉得对你有帮助,关注博客和公众号。不定期分享最新前沿技术框架和bat大厂常用技术等,加群不定期分享行业内大牛直播讲课以及获得视频课件资料等。

发表评论

表情:
评论列表 (有 0 条评论,328人围观)

还没有评论,来说两句吧...

相关阅读