LeetCode第13题,Roman to Integer(Java)

 LeetCode第13题是将罗马数字转换成阿拉伯数字,也就是我们常用的十进制。(LeetCode第12题是将数字转换成罗马数字,此题相反)

 首先,罗马数字用字符串表示,阿拉伯数字用整型表示。先分析给出的几个示例:

  1.第一个给出的字符串是罗马数"III”,通过以下对应表,我们遍历累加就可以得出结果是3,简单

    Symbol Value

     I     1

    V     5

    X     10

    L     50

    C     100

    D     500

    M     1000

  2.第2个给出的字符串是“IV”,第一个代表1,第2个代表5,“IV”代表(5-1=)4,“VI”表示(5+1=)6。所以像4,9,40,90这种,我们不能直接累加,必须判断前后大小关系再累加

  3.第3个字符串是"IX",和第2个类似,X表示10,所以“IX”表示9。

  4.直接累加50+5+1+1+1 = 58

  5,再看最后一个字符串“MCMXCIV”,M代表1000,C代表100,后面第3个字母M代表1000,这里就应该C和M连起来代表900,然后第4个字母X,X是代表10呢,还是让第5个字母相减呢,

所以还得继续看第5个字母C,C代表100,比X的10大,所以这里CM代表90,剩下最后两个字母“IV”代表4。所以结果就是1000(M)+900(CM)+90(XC)+4(IV) = 1994。

  这个时候我们可以有个思路,从第1个字符串开始遍历,我们比较 当前字符串转换成的数字 和 后一个字符串转换成的数字的大小,如果当前数字更大,直接累加,如果后一个数字比当前数字更大,

后一个数字减去当前数字再累加,并将遍历的下标索引跳一格(多加1)。

  这个时候会有个问题,如果是“IVI”,第1个字母和第2个字母比较以后,剩下第3个字母,没有下一个字母,怎么办?

  所以,在遍历的时候,去除了最后一个索引,如果刚好类似“IVIV”这种,遍历后索引的值刚好等于字符串长度,如果类似“IVI”这样,遍历后索引的值比字符串的长度小1。

  因为Jdk1.7之后,switch语句支持字符串,而且这里要多次字符串查找转换成数字,所以单独一个方法查找字符对应的数字。

  以下是详细代码:

  代码1:

  

 1 public class Test1 {
 2 
 3     public static void main(String[] args) {
 4         System.out.println(romanToInt("III"));
 5         System.out.println(romanToInt("IV"));
 6         System.out.println(romanToInt("IX"));
 7         System.out.println(romanToInt("LVIII"));
 8         System.out.println(romanToInt("MCMXCIV"));
 9         System.out.println(romanToInt(""));
10         System.out.println(romanToInt(null));
11         System.out.println(romanToInt("C"));
12     }
13     
14     public static int romanToInt(String s) {
15         if (s == null) {
16             return 0;
17         }
18         int sum = 0, i = 0, len = s.length();
19         int current = 0, next = 0;
20         for (; i < len - 1; i++) {
21             current = findNumber(s.charAt(i) + "");
22             next = findNumber(s.charAt(i + 1) + "");
23             if (current >= next) {            //如果当前罗马字母转成的数字比后一个字母转成的数字大,直接加到结果里面
24                 sum += current;
25             } else {                        
26                 sum += next - current;        //否则将后一个数字减去当前数字,再加到结果里
27                 i++;                        //并将i的值多加1位
28             }
29         }
30         if (i < len) {  //如果i小于字符串的长度,说明还有最后一个字符串没有转化成数字
31             sum += findNumber(s.charAt(len- 1) + "");
32         }
33         
34         return sum;
35     }
36     //查找罗马字符对应的数字
37     private static int findNumber(String str) {
38         int number = 0;
39         switch(str) {
40         case "I":
41             number = 1;
42             break;
43         case "V":
44             number = 5;
45             break;
46         case "X":
47             number = 10;
48             break;
49         case "L":
50             number = 50;
51             break;
52          case "C":
53             number = 100;
54             break;
55          case "D":
56             number = 500;
57             break;
58          case "M":
59             number = 1000;
60             break;
61          default:
62              break;
63         }
64         return number;
65     }
66 
67 }

  运行时间:

  

  后面我想了一下,我们可以有另一种思路,先把罗马数字代表的数字先相加,然后判断相邻的大小关系,

从索引1开始,判断当前字符转换后的数字和前一个字符转换后的数字的大小关系。如果前一个数字更小,则双倍减去前一个数字。

(比如原本“IV”代表4,直接累加后变成6,6 - 1 *2 = 4,必须减去那个数字的两倍),这样能一直遍历到最后一个字符。

注意这里是遍历了两次,先累加,然后再判断大小关系又遍历了一次。

代码2:

 

 1 public class Test2 {
 2 
 3     public static void main(String[] args) {
 4         System.out.println(romanToInt("III"));
 5         System.out.println(romanToInt("IV"));
 6         System.out.println(romanToInt("IX"));
 7         System.out.println(romanToInt("LVIII"));
 8         System.out.println(romanToInt("MCMXCIV"));
 9         System.out.println(romanToInt(""));
10         System.out.println(romanToInt(null));
11         System.out.println(romanToInt("C"));
12     }
13     
14     public static int romanToInt(String s) {
15         if (s == null || s.length() < 1) {
16             return 0;
17         }
18         int sum = 0, len = s.length();
19         int current = 0, previous = 0;
20         for (int i = 0; i < len; i++) {
21             current = findNumber(s.charAt(i) + "");
22             sum += current;
23         }
24         for (int i = 1; i < len; i++) {
25             previous = findNumber(s.charAt(i - 1) + "");
26             current = findNumber(s.charAt(i) + "");
27             if (previous < current) {
28                 sum -= previous * 2;
29             }
30         }
31         
32         return sum;
33     }
34     //查找罗马字符对应的数字
35     private static int findNumber(String str) {
36         int number = 0;
37         switch(str) {
38         case "I":
39             number = 1;
40             break;
41         case "V":
42             number = 5;
43             break;
44         case "X":
45             number = 10;
46             break;
47         case "L":
48             number = 50;
49             break;
50          case "C":
51             number = 100;
52             break;
53          case "D":
54             number = 500;
55             break;
56          case "M":
57             number = 1000;
58             break;
59          default:
60              break;
61         }
62         return number;
63     }
64 
65 }

运行时间:

  

  后面还有对第2个代码稍微改进:

 代码3:

  

 1 public class Test3 {
 2 
 3     public static void main(String[] args) {
 4         System.out.println(romanToInt("III"));
 5         System.out.println(romanToInt("IV"));
 6         System.out.println(romanToInt("IX"));
 7         System.out.println(romanToInt("LVIII"));
 8         System.out.println(romanToInt("MCMXCIV"));
 9         System.out.println(romanToInt(""));
10         System.out.println(romanToInt(null));
11         System.out.println(romanToInt("C"));
12     }
13     
14     public static int romanToInt(String s) {
15         if (s == null || s.length() < 1) {
16             return 0;
17         }
18         int sum = 0, len = s.length();
19         int current = 0, previous = 0;
20         
21         sum += findNumber(s.charAt(0) + "");
22         for (int i = 1; i < len; i++) {
23             previous = findNumber(s.charAt(i - 1) + "");
24             current = findNumber(s.charAt(i) + "");
25             sum += current;
26             if (previous < current) {
27                 sum -= previous * 2;
28             } 
29         }
30         
31         return sum;
32     }
33     //查找罗马字符对应的数字
34     private static int findNumber(String str) {
35         int number = 0;
36         switch(str) {
37         case "I":
38             number = 1;
39             break;
40         case "V":
41             number = 5;
42             break;
43         case "X":
44             number = 10;
45             break;
46         case "L":
47             number = 50;
48             break;
49          case "C":
50             number = 100;
51             break;
52          case "D":
53             number = 500;
54             break;
55          case "M":
56             number = 1000;
57             break;
58          default:
59              break;
60         }
61         return number;
62     }
63 
64 }

  运行时间:

  

  

猜你喜欢

转载自www.cnblogs.com/yxbainian/p/10271323.html