부부의 코딩 성장 일기

LeetCode 17(Letter Combinations of a Phone Number, Python) 본문

Algorithm/LeetCode

LeetCode 17(Letter Combinations of a Phone Number, Python)

제로_콜라 2023. 12. 16. 19:00

1. 문제 링크

 

Letter Combinations of a Phone Number - LeetCode

Can you solve this real interview question? Letter Combinations of a Phone Number - Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent. Return the answer in any order. A mapping of d

leetcode.com

2. 문제 설명

  • 휴대폰 다이얼 버튼 2에는 abc, 3에는 def가 대응됨.
  • digits=’23’이 주어지면 대응될 수 있는 모든 문자열을 모은 리스트 [’ad’, ‘ae’, ‘af’, ‘bd’, ‘be’, ‘bf’, ‘cd’, ‘ce’, ‘cf’]를 반환하는 문제

3. 처음 풀이

  • 다이얼과 문자를 대응시키는 {‘2’:’abc’, ‘3’:’def’, …, ‘9’:’wxyz’} 딕셔너리를 생성
  • digit=’23’ 일 때 2에 해당하는 result = [’a’,’b’,’c’]가 만들어져있다고 하자.
  • 주어진 digits을 앞에서부터 순회하는 for문을 돌리고
  • 2 다음 3이 나오면 딕셔너리에서 ‘def’를 꺼냄.
  • 이미 만들어진 result의 각 문자열 ‘a’, ‘b’, ‘c’와 꺼낸 ‘def’에 대해 이중 for문을 돌려 ‘a’+’d’ 부터 ‘c’+’f’까지 result 업데이트

 

class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        # 각 숫자에 해당하는 문자들을 매핑한 딕셔너리
        numtoletter = {'2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl', '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz'}
        
        # 초기 결과 리스트
        result = ['']

        # 입력된 숫자가 없으면 빈 리스트를 반환합니다.
        if digits == '':
            return []

        # 각 숫자에 대해 가능한 문자 조합을 생성
	# 예시) result = ['abc'], i=3 -> ad, ae, af, bd, be, bf, cd, ce, cf
        for i in digits:
            result = [x + y for x in result for y in numtoletter[i]]

        # 결과를 반환
        return result

4. 다른 풀이

  • backtracking 이용한 풀이
  • 재귀 함수에 현재까지 만들어진 문자열 조합과, 남은 digits 두 인자를 전달
  • 시간 복잡도는 원래 풀이와 같고 실제 런타임도 비슷. 굳이 재귀적으로 푸는 장점이 있는 것 같지는 않음
class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        if not digits:
            return []

        # 각 숫자에 해당하는 문자들을 매핑한 딕셔너리
        phone_map = {
            '2': 'abc',
            '3': 'def',
            '4': 'ghi',
            '5': 'jkl',
            '6': 'mno',
            '7': 'pqrs',
            '8': 'tuv',
            '9': 'wxyz'
        }

        def backtrack(combination, next_digits):
            # 다음 숫자가 없을 때, 조합을 결과에 추가하고 종료합니다.
            if len(next_digits) == 0:
                output.append(combination)
            else:
                # 현재 숫자에 대한 각 문자에 대해 재귀적으로 진행합니다.
                for letter in phone_map[next_digits[0]]:
                    backtrack(combination + letter, next_digits[1:])

        output = []
        # 초기에는 빈 문자열과 입력된 숫자로 재귀적으로 진행합니다.
        backtrack("", digits)
        return output

5. 배운 점

  • list comprehension 을 이중으로 쓸 수 있고, 원한다면 if문도 쓸 수 있음.

  • backtracking(퇴각검색)이란?
  • backtracking의 사용
    • 재귀함수와 사용되는 경우가 많으며
    • 후보 선택 → 다음 단계 진행 → 조건 확인 → 해결 or 이전 단계로 돌아가기 의 반복
    • 가지치기를 하여 모든 경우를 따지는 깊이 우선 탐색을 하며, 절대로 답이 될 수 없는 경우임을 판단하면 그 이전 단계로 돌아가는 것이 backtracking의 예시
  • 대표적인 문제
    • n-qeen 문제, n*n 격자에 n개의 퀸을 놓는데, 같은 세로, 가로, 대각선에 퀸이 동시에 있으면 안됨.
    • n개의 퀸을 모두 가능한 곳에 놓아보고 따지면 오래걸림
    • 따라서 하나의 퀸을 놓을 때마다 조건을 만족하는 지 따져보고, 해가 될 수 없다면 그 이전 퀸을 다음 칸에 놓고 계속해서 탐색.

 

'Algorithm > LeetCode' 카테고리의 다른 글

LeetCode 19(Remove Nth Node From End of List, Python)  (1) 2023.12.18
LeetCode 18(4Sum, Python)  (1) 2023.12.17
LeetCode 16(3Sum Closest, Python)  (1) 2023.12.15
LeetCode 15(3Sum, Python)  (0) 2023.12.14
LeetCode 12(Integer to Roman, Python)  (0) 2023.12.13