본문 바로가기
알고리즘/LeetCode

[LeetCode] 013. Roman to Integer JAVA

by Bhinney 2022. 12. 30.

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


 ☀️ 문제

Roman numerals are represented by seven different symbols: 
I, V, X, L, C, D and M.

For example, 2 is written as II in Roman numeral, just two ones added together. 12 is written as XII, which is simply X + II. The number 27 is written as XXVII, which is XX + V + II.
Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:

• I can be placed before V (5) and X (10) to make 4 and 9. 
• X can be placed before L (50) and C (100) to make 40 and 90. 
• C can be placed before D (500) and M (1000) to make 400 and 900.

Given a roman numeral, convert it to an integer.
로마 숫자는 I, V, X, L, C, D 및 M의 7가지 기호로 표시됩니다.

예를 들어, 2는 로마 숫자로 II로 표기되며, 1을 2개만 더하면 됩니다.
12는 XII로 표기되며, 간단히 X + II입니다.
숫자 27은 XXVII로 표기되며, 이는 XX + V + II입니다.
로마 숫자는 일반적으로 왼쪽에서 오른쪽으로 큰 순서로 씁니다.
그러나 4의 숫자는 IIII가 아닙니다. 대신 숫자 4는 IV로 씁니다. 1이 5보다 앞에 있기 때문에 빼면 4가 됩니다.
같은 원리가 IX로 쓰여진 숫자 9에도 적용됩니다. 빼기가 사용되는 경우는 6가지입니다.

• V(5)와 X(10) 앞에 I를 배치하여 4와 9를 만들 수 있습니다.
• X는 L(50)과 C(100) 앞에 배치하여 40과 90을 만들 수 있습니다.
• C는 D(500)와 M(1000) 앞에 배치되어 400과 900을 만들 수 있습니다.

로마 숫자가 주어지면 정수로 변환하십시오.

 

 


☀️ 예시

Input: s = "III"
Output: 3
Explanation: III = 3.
Input: s = "LVIII"
Output: 58
Explanation: L = 50, V= 5, III = 3.
Input: s = "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.

☀️ 풀이 설명

  • 이 문제는 몇일 전에 푼 https://bhinney.tistory.com/190 이 문제의 반대 문제이다.
  • 각 기호의 값을 구할 함수를 생성한다.
  • 각 기호의 값은 위의 사진과 같다.
public static int getNum(char character) {
   switch (character) {
      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;}
   }
}

  • 각 해당 문자의 값을 더해야하기 때문에 sum이라는 변수를 생성하고 초기화 해주었다.
  • 문자열의 길이만큼 반복문을 돌며 각 문자의 값을 가져와준다.
public static int romanToInt(String s) {
   int sum = 0;
   for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);
      int num = getNum(c);
   }
   return sum;
}

  • 다음 수를 비교해야하는 데, 다음 수가 존재하지 않을 수 있다.
  • 따라서 존재하지 않으면, continue로 다음 반복문으로 넘어가도록 하였다.
public static int romanToInt(String s) {
   int sum = 0;
   for (int i = 0; i < s.length(); i++) {
      
      ...

      /* 만약 다음 수가 없다면 */
      if (i + 1 == s.length()) {
         sum += num;
         continue;
      }
   }
   return sum;
}

  • 다음에 오는 수가 현재의 수보다 클 경우 빼야한다.
  • 그래서 다음 수를 가져온 후, 현재의 숫자와 비교한다.
  • 만약 뒤에 오는 수가 크면 현재의 값을 빼주고, 만약 뒤에 오는 수가 작으면 현재의 값을 더해준다.
  • 지금 수를 빼고 다음 수를 더하면, 해당 값이 나온다.
  • 예시 : IV 는 4이다. I는 1이고 V는 5이다. -1 + 5 는 4가 된다.
public static int romanToInt(String s) {
   int sum = 0;
   for (int i = 0; i < s.length(); i++) {
      
      ...

      /* 뒤에 오는 수가 지금 현재보다 크면 빼야함 */
      char next = s.charAt(i + 1);
      if (num < getNum(next)) {
         sum -= num;
      } else {
         sum += num;
      }
   }
   return sum;
}

☀️  최종 풀이

public static int romanToInt(String s) {
   int sum = 0;
   for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);
      int num = getNum(c);

      /* 만약 다음 수가 없다면 */
      if (i + 1 == s.length()) {
         sum += num;
         continue;
      }

      /* 뒤에 오는 수가 지금 현재보다 크면 빼야함 */
      char next = s.charAt(i + 1);
      if (num < getNum(next)) {
         sum -= num;
      } else {
         sum += num;
      }
   }
   return sum;
}

/* 비교할 수 있는 메서드 생성 */
public static int getNum(char character) {
   switch (character) {
      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 1; }
   }
}

댓글