题目描述(简单难度)

13. Roman to Integer - 图1

和上一道题相反,将罗马数字转换成阿拉伯数字。

解法一

先来一种不优雅的,也就是我开始的想法。就是遍历字符串,然后转换就可以,但同时得考虑 IV,IX 那些特殊情况。

  1. public int getInt(char r) {
  2. int ans = 0;
  3. switch (r) {
  4. case 'I':
  5. ans = 1;
  6. break;
  7. case 'V':
  8. ans = 5;
  9. break;
  10. case 'X':
  11. ans = 10;
  12. break;
  13. case 'L':
  14. ans = 50;
  15. break;
  16. case 'C':
  17. ans = 100;
  18. break;
  19. case 'D':
  20. ans = 500;
  21. break;
  22. case 'M':
  23. ans = 1000;
  24. }
  25. return ans;
  26. }
  27. public int getInt(char r, char r_after) {
  28. int ans = 0;
  29. switch (r) {
  30. case 'I':
  31. ans = 1;
  32. break;
  33. case 'V':
  34. ans = 5;
  35. break;
  36. case 'X':
  37. ans = 10;
  38. break;
  39. case 'L':
  40. ans = 50;
  41. break;
  42. case 'C':
  43. ans = 100;
  44. break;
  45. case 'D':
  46. ans = 500;
  47. break;
  48. case 'M':
  49. ans = 1000;
  50. break;
  51. }
  52. if (r == 'I') {
  53. switch (r_after) {
  54. case 'V':
  55. ans = 4;
  56. break;
  57. case 'X':
  58. ans = 9;
  59. }
  60. }
  61. if (r == 'X') {
  62. switch (r_after) {
  63. case 'L':
  64. ans = 40;
  65. break;
  66. case 'C':
  67. ans = 90;
  68. }
  69. }
  70. if (r == 'C') {
  71. switch (r_after) {
  72. case 'D':
  73. ans = 400;
  74. break;
  75. case 'M':
  76. ans = 900;
  77. }
  78. }
  79. return ans;
  80. }
  81. public boolean isGetTwoInt(char r, char r_after) {
  82. if (r == 'I') {
  83. switch (r_after) {
  84. case 'V':
  85. return true;
  86. case 'X':
  87. return true;
  88. }
  89. }
  90. if (r == 'X') {
  91. switch (r_after) {
  92. case 'L':
  93. return true;
  94. case 'C':
  95. return true;
  96. }
  97. }
  98. if (r == 'C') {
  99. switch (r_after) {
  100. case 'D':
  101. return true;
  102. case 'M':
  103. return true;
  104. }
  105. }
  106. return false;
  107. }
  108. public int romanToInt(String s) {
  109. int ans = 0;
  110. for (int i = 0; i < s.length() - 1; i++) {
  111. ans += getInt(s.charAt(i), s.charAt(i + 1));
  112. //判断是否是两个字符的特殊情况
  113. if (isGetTwoInt(s.charAt(i), s.charAt(i + 1))) {
  114. i++;
  115. }
  116. }
  117. //将最后一个字符单独判断,如果放到上边的循环会越界
  118. if (!(s.length() >= 2 && isGetTwoInt(s.charAt(s.length() - 2), s.charAt(s.length() - 1)))) {
  119. ans += getInt(s.charAt(s.length() - 1));
  120. }
  121. return ans;
  122. }

时间复杂度:O(n),n 是字符串的长度。

空间复杂度:O(1)。

下边分享一些优雅的。

解法二

https://leetcode.com/problems/roman-to-integer/description/

  1. public int romanToInt(String s) {
  2. int sum=0;
  3. if(s.indexOf("IV")!=-1){sum-=2;}
  4. if(s.indexOf("IX")!=-1){sum-=2;}
  5. if(s.indexOf("XL")!=-1){sum-=20;}
  6. if(s.indexOf("XC")!=-1){sum-=20;}
  7. if(s.indexOf("CD")!=-1){sum-=200;}
  8. if(s.indexOf("CM")!=-1){sum-=200;}
  9. char c[]=s.toCharArray();
  10. int count=0;
  11. for(;count<=s.length()-1;count++){
  12. if(c[count]=='M') sum+=1000;
  13. if(c[count]=='D') sum+=500;
  14. if(c[count]=='C') sum+=100;
  15. if(c[count]=='L') sum+=50;
  16. if(c[count]=='X') sum+=10;
  17. if(c[count]=='V') sum+=5;
  18. if(c[count]=='I') sum+=1;
  19. }
  20. return sum;
  21. }

把出现的特殊情况,提前减了就可以。

时间复杂度:O(1)。

空间复杂度:O(1)。

解法三

https://leetcode.com/problems/roman-to-integer/discuss/6509/7ms-solution-in-Java.-easy-to-understand

利用到罗马数字的规则,一般情况是表示数字大的字母在前,数字小的字母在后,如果不是这样,就说明出现了特殊情况,此时应该做减法。

  1. private int getVal(char c){
  2. switch (c){
  3. case 'M':
  4. return 1000;
  5. case 'D':
  6. return 500;
  7. case 'C':
  8. return 100;
  9. case 'L':
  10. return 50;
  11. case 'X' :
  12. return 10;
  13. case 'V':
  14. return 5;
  15. case 'I':
  16. return 1;
  17. }
  18. throw new IllegalArgumentException("unsupported character");
  19. }
  20. public int romanToInt(String s) {
  21. int res = 0;
  22. if(s.length() == 0) return res;
  23. for (int i = 0; i < s.length() - 1; i++) {
  24. int cur = getVal(s.charAt(i));
  25. int nex = getVal(s.charAt(i+1));
  26. if(cur < nex){
  27. res -= cur;
  28. }else{
  29. res += cur;
  30. }
  31. }
  32. return res + getVal(s.charAt(s.length()-1));
  33. }

时间复杂度:O(1)。

空间复杂度:O(1)。

这道题也不难,自己一开始没有充分利用罗马数字的特点,而是用一些 if,switch 语句判断是否是特殊情况,看起来就很繁琐了。

windliang wechat

添加好友一起进步~

如果觉得有帮助的话,可以点击 这里 给一个 star 哦 ^^

如果想系统的学习数据结构和算法,强烈推荐一个我之前学过的课程,可以点击 这里 查看详情