LeetCode - Roman numeral to integer E[13]

  • Problem Description:

 

Roman numerals contain the following seven characters: I, V, X, L, C, D and M. 

Character value
I             1
V             5
X             10
L             50
C             100
D             500
M             1000 

 For example, the Roman numeral 2 is written as II, which is two parallel ones. 12 is written as XII, which is X + II. 27 is written as XXVII, which is XX + V + I + I.

 Usually, the small Roman numerals are to the right of the large ones. But there are also special cases. For example, 4 is not written as IIII, but IV. The number 1 is to the left of the number 5 and represents a number equal to the large number 5
 The value 4 obtained by subtracting decimal 1. Similarly, the number 9 is represented as IX. This special rule applies only to the following six cases: 

 I can be placed to the left of V (5) and X (10) to represent 4 and 9.
 X can be placed to the left of L (50) and C (100) to represent 40 and 90. 
 C can be placed to the left of D (500) and M (1000) to represent 400 and 900. 

Given a Roman numeral, convert it to an integer. Make sure the input is in the range of 1 to 3999.

Example 1:
  Input:   "III"
  Output: 3

Example 2:
  Input:   "IV"
  Output: 4

Example 3:
  Input:   "IX"
  Output: 9

Example 4:
  Input:   "LVIII"
  Output: 58
  Explanation: L = 50, V= 5, III = 3

Example 5:
  Input:   "MCMXCIV"
  Output: 1994
  Explanation: M = 1000, CM = 900, XC = 90, IV = 4

 Tip: 1 < = s.length < = 15
 s contains only characters ('I ',' V ',' x ',' l ',' C ','d','m ') 
 The title data ensures that s is a valid Roman numeral and represents an integer in the range [1, 3999] 
 The test cases given in the title comply with the Roman numeral writing rules, and there will be no cross position and so on. 
 Examples such as IL and IM do not meet the title requirements. 49 should write XLIX and 999 should write CMXCIX. 

Solution idea 1:

        According to the title description, there are six situations: IV, IX, XL, XC, CD, CM, and then directly if else according to the situation.

         code:

        char[] chars = s.toCharArray();
        int length = chars.length;
        int num = 0;

        for(int i = 0;i < length;i++){
            if(chars[i] == 'I'){
                if(i + 1 < length){
                    if(chars[i + 1] == 'V'){
                        num += 4;
                        i += 1;
                        continue;
                    }
                    if(chars[i + 1] == 'X'){
                        num += 9;
                        i += 1;
                        continue;
                    }
                }
            }
            if(chars[i] == 'X'){
                if(i + 1 < length){
                    if(chars[i + 1] == 'L'){
                        num += 40;
                        i += 1;
                        continue;
                    }
                    if(chars[i + 1] == 'C'){
                        num += 90;
                        i += 1;
                        continue;
                    }
                }
            }
            if(chars[i] == 'C'){
                if(i + 1 < length){
                    if(chars[i + 1] == 'D'){
                        num += 400;
                        i += 1;
                        continue;
                    }
                    if(chars[i + 1] == 'M'){
                        num += 900;
                        i += 1;
                        continue;
                    }
                }
            }

            switch (chars[i]){
                case 'I':
                    num += 1;
                    break;
                case 'V':
                    num += 5;
                    break;
                case 'X':
                    num += 10;
                    break;
                case 'L':
                    num += 50;
                    break;
                case 'C':
                    num += 100;
                    break;
                case 'D':
                    num += 500;
                    break;
                case 'M':
                    num += 1000;
                    break;
            }
        }
        return num;

Execution results:

The result is good, but the code seems too bloated, not concise enough for others to understand.

Problem solving idea 2:

          From the title, generally speaking, the number on the left of Roman numerals is greater than the number on the right, so it can be calculated in order.

XXVII = X + X + V + I + I = 10 + 10 + 5 + 1 + 1 = 27.

  If the number on the left is less than the number on the right, subtract the number to be subtracted according to the rules.

XIV = X - I + V = 10 - 1 + 5 = 14

code:

    int length = s.length();
        int num = getValue(s.charAt(0));
        int vue = 0;
        for(int i = 1;i < length;i++){
            int value = getValue(s.charAt(i));
            if( num < value){
                vue -= num;
            }else {
                vue += num;
            }
            num = value;
        }
        vue += num;
        return vue;

    
    Call method:
    public int getValue(char c){
        switch (c){
            case 'I':
                return 1;
            case 'V':
                return 5;
            case 'X':
                return 10;
            case 'L':
                return 50;
            case 'C':
                return 100;
            case 'D':
                return 500;
            case 'M':
                return 1000;
                default:
                    return 0;
        }
    }

  Of course, you can store data in a HashMap without using this method, but it seems that the efficiency is not very good because the amount of data is too small.

Map collection:
Map<Character,Integer> map = new HashMap<>();
map.put('I',1);
map.put('V',5);
map.put('X',10);
map.put('L',50);
map.put('C',100);
map.put('D',500);
map.put('M',1000); 

  Execution results:

Tags: Java Algorithm leetcode

Posted on Tue, 21 Sep 2021 03:28:07 -0400 by leap500