부부의 코딩 성장 일기

LeetCode 12(Integer to Roman, Python) 본문

Algorithm/LeetCode

LeetCode 12(Integer to Roman, Python)

펩시_콜라 2023. 12. 13. 19:00

1. 문제 링크

2. 문제 설명

  • 우리가 쓰는 정수가 주어지면 Roman 숫자로 바꾸어 return 하는 문제
  • 아래의 기호를 이용함
    • I: 1
    • V: 5
    • X: 10
    • L: 50
    • L: 100
    • D: 500
    • M: 1000
  • 이 때,
    • I는 V,X 앞에 쓰여서 4,9를 나타냄
    • X는 L,C 앞에 쓰여서 40,90을 나타냄
    • C는 D,M 앞에 쓰여서 400,900을 나타냄 
  • 예시)
    • 3 → III, 58 → LVIII, 1994 → MCMXCIV

3. 처음 풀이

  • 딱히 특별한 알고리즘이 없을 것 같아서,
  • 정수에 매칭되는 로마 문자에 대한 dictionary를 만들어두고,
  • num 이 특정 숫자 이상이면, 그 숫자에 대한 로마 문자를 concat하고, num에서 해당 숫자를 반환하는 구조를 반복
    • 코드가 if문 밭이어서 지저분하긴 하지만 runtime 95% beats!
class Solution:
    def intToRoman(self, num: int) -> str:
        roman_dict = {
            1000: 'M', 900: 'CM', 500: 'D', 400: 'CD',
            100: 'C', 90: 'XC', 50: 'L', 40: 'XL',
            10: 'X', 9: 'IX', 5: 'V', 4: 'IV', 1: 'I'
        }
        result = ''

        while(num !=0):
            if num >= 1000:
                result += roman_dict[1000]
                num = num - 1000
            elif num >= 900: 
                result += roman_dict[900]
                num = num - 900 
            elif num >= 500: 
                result += roman_dict[500]
                num = num - 500 
            elif num >= 400: 
                result += roman_dict[400]
                num = num - 400 
            elif num >= 100: 
                result += roman_dict[100]
                num = num - 100 
            elif num >= 90: 
                result += roman_dict[90]
                num = num - 90 
            elif num >= 50: 
                result += roman_dict[50]
                num = num - 50 
            elif num >= 40: 
                result += roman_dict[40]
                num = num - 40 
            elif num >= 10: 
                result += roman_dict[10]
                num = num - 10 
            elif num >= 9: 
                result += roman_dict[9]
                num = num - 9 
            elif num >= 5: 
                result += roman_dict[5]
                num = num - 5 
            elif num >= 4: 
                result += roman_dict[4]
                num = num - 4 
            elif num >= 1: 
                result += roman_dict[1]
                num = num - 1 

        return result

 

4. 다른 풀이

  • 다른 풀이를 봐도 if문이나 while으로 길게 쓴 코드가 많았는데,,
  • gpt한테 물어보니 깔끔하고 간결한 코드를 내어주었다.
  • 처음 고민포인트가 num이 1994일 때, 이것과 가장 가까운 정수인 1000을 기준으로 두는 걸 어떻게 셋팅하느냐였는데...
    • roman_dict을 내림차순으로 구성하고,
    • roman_dict을 for 루프를 돌리면서, 위에 내가 짰던 while문을 추가하면,, 세상 간결하게 코드가 짜진다. 
  • 내 코드의 단점은, roman_dict이 길어질 수록, 코드가 계속 길어지고, 위 아래로 코드를 수정해주어야 한다는 것인데, 
  • gpt 코드는 확장성이 좋다.
class Solution:
    def intToRoman(self, num: int) -> str:
        roman_dict = {
            1000: 'M', 900: 'CM', 500: 'D', 400: 'CD',
            100: 'C', 90: 'XC', 50: 'L', 40: 'XL',
            10: 'X', 9: 'IX', 5: 'V', 4: 'IV', 1: 'I'
        }
        
        result = ''
        for value, numeral in roman_dict.items():
            while num >= value:
                result += numeral
                num -= value
        
        return result

 

5. 배운점

  •  파이썬 3.7부터는 딕셔너리 순서가 유지되기 때문에 성질을 이용하면 유용
  • 예를 들면 나이대별로 명칭을 부여하거나 금액을 부여할 때 if문으로 여러 케이스를 다룰 필요가 없음
# 파이썬 3.7 이상에서는 딕셔너리의 순서가 유지됩니다.
age_groups = {
    0: 'Infant',
    5: 'Child',
    12: 'Preteen',
    18: 'Teenager',
    30: 'Young Adult',
    50: 'Middle-Aged',
    65: 'Senior',
    100: 'Centenarian'
}

# 연령에 따라 그룹을 출력
age = 25
for threshold in sorted(age_groups.keys()):
    if age < threshold:
        print(f"A person aged {age} falls into the '{age_groups[threshold]}' category.")
        break