[LeetCode] 273. Integer to English Words

📃 문제 설명

(HARD) https://leetcode.com/problems/integer-to-english-words/

  • 0에서 2^31 - 1 사이의 non-negative integer num을 input으로 받아, English word로 반환하는 문제이다.

Example 1:

Input: num = 123
Output: "One Hundred Twenty Three"

Example 2:

Input: num = 12345
Output: "Twelve Thousand Three Hundred Forty Five"

Example 3:

Input: num = 1234567
Output: "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"

Example 4:

Input: num = 1234567891
Output: "One Billion Two Hundred Thirty Four Million Five Hundred Sixty Seven Thousand Eight Hundred Ninety One"

🔎 문제 접근

  • 영어로 숫자를 표기할 때 세 자리씩 끊어서 읽게 된다. 따라서 주어진 수를 '백의 자리 수를 읽는 공통의 규칙' + '단위' 의 조합으로 생각하면 되겠다는 생각이 들었다.
  • 2^31 - 1 = 2,147,483,647로, 최대 접근 가능 단위는 billion임을 체크했다.
  • '백의 자리 수를 읽는 공통의 규칙'은 백의 자리 수 + 십의 자리 이하의 수 에 대해 규칙이 또 다르다.
    • 백의 자리 수는 숫자 + hundred
    • 십의 자리 이하 수는
      • 1에서 9까지는 one ~ nine
      • 10에서 19까지는 ten ~ nineteen
      • 20 이상부터는 10의 자리수 + 1에서 9
    • 로 읽는 방법이 굉장히 다양하다. 따라서 주어진 규칙에 대해 array를 사전에 제작해두어 계산 시간을 약간이나마 줄였다.
  • 해당 문제는 '띄어쓰기' 또한 잘 맞춰줘야 된다. 각 블록에 대해 동일한 규칙을 적용해 상황에 따라 띄어쓰기가 아예 없거나, 띄어쓰기가 두 번 이상 나오지 않도록 관리해야 한다.

✨ 문제 풀이

class Solution:
    def __init__(self):
        self.oneDigitEnglishWord = ["", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"]
        self.tenthEnglishWord = ["", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"]
        self.elevenishEnglishWord = ["", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"]
    
    # 마지막에 띄어쓰기 없이 출력, 함수 출력값들 사이 연결 시 띄어쓰기 필요 
    def calcEnglishWord(self, num: int, unit: str):
    	# 0이면 빈칸 반환
        if num == 0:
            return ""
        
        ans = ""
        #백의 자리에 대해 계산
        if num // 100:
            ans += self.oneDigitEnglishWord[num // 100] + " Hundred "
        
        #10의 자리 이하에 대해 계산
        if 1 <= num % 100 <= 9:
            ans += self.oneDigitEnglishWord[num % 100] + " "
        elif 11 <= num % 100 <= 19:
            ans += self.elevenishEnglishWord[num % 10] + " "
        else:
            tmp = self.tenthEnglishWord[(num // 10) % 10]
            if tmp: #출력값이 존재하지 않을 경우에 발생하는 띄어쓰기 방지
                ans += tmp + " "
            
            tmp = self.oneDigitEnglishWord[num % 10]
            if tmp:
                ans += tmp + " "
        
        return ans + unit    
        
    def numberToWords(self, num: int) -> str:
        if num == 0:
            return "Zero"
        
        real_ans = ""
        
        tmp = self.calcEnglishWord(num // 10**9, "Billion")
        real_ans += tmp
        
        tmp = self.calcEnglishWord((num // 10**6) % 1000, "Million")
        if real_ans and tmp:
            real_ans += " " + tmp
        else: #출력값이 존재하지 않을 경우에 발생하는 띄어쓰기 방지
            real_ans += tmp
        
        tmp = self.calcEnglishWord((num // 10**3) % 1000, "Thousand")
        if real_ans and tmp:
            real_ans += " " + tmp
        else:
            real_ans += tmp
            
        tmp = self.calcEnglishWord(num % 1000, "")
        if real_ans and tmp:
            real_ans += " " + tmp
        else:
            real_ans += tmp
        
        #마지막에 생기는 띄어쓰기 지워주기
        while len(real_ans) and real_ans[-1] == " ":
            real_ans = real_ans[:-1]
            
        return real_ans

  • 꽤나 빠른 결과를 얻을 수 있었다.

좋은 웹페이지 즐겨찾기