본문 바로가기

Algorithm

[leetcode] Letter Combinations of a Phone Number

문제

https://leetcode.com/problems/letter-combinations-of-a-phone-number/description/

 

Letter Combinations of a Phone Number - LeetCode

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 digits to letters (just like on the telephone

leetcode.com

문제요약

2~9번의 전화번호를 눌렀을 때, 가능한 문자열을 전부 구하는 문제입니다. 

풀이 

이 문제는 풀이 공유보다는 간결한 코드를 공유하기 위해 작성했습니다! 풀이는 아래와 같아요.

먼저, 입력된 숫자를 순회하며 가능한 문자열을 배열에 넣습니다. 그리고 다음 숫자를 순회할 때, 배열에 저장된 문자열에 계속 가능한 문자열들을 추가하면서 답을 구할 수 있습니다. 코드를 간단하게 작성하기 위해 주목할 점은 "계속 문자열을 추가"한다는 점입니다. 

문자열 3개가 있는 배열에서 다음 숫자가 3일경우 "d", "e", "f" 3가지 경우의 수가 있기 때문에 3 x 3, 총 9가지 문자열이 생깁니다. 늘어나는 개수는 배열의 개수 x 더해질 문자의 개수입니다. 이것을 타입으로 표현해보면 아래와 같습니다.

 

[String] -> [[String]]-> [String]

 

배열을 걷어내고 다시 [String] 타입을 얻기위해서 고차함수 flatmap을 사용할 수 있습니다. 

 

map과는 차이가 있기에, 먼저 map의 예시를 들어보겠습니다.

var strings = ["1","2","3"]
strings = strings.map { item in
    return item
}
print(strings)

/// ["1", "2", "3"]

item의 타입은 String이고 map은 for문과 동작방식이 비슷하기에 배열의 element타입을 반환해야합니다. 

 

flatmap은 위와 같이 사용되기도 하지만(이런 경우는 그냥 map을 사용합니다), 배열을 한번 걷어줍니다. 

var strings = ["1","2","3"]
strings = strings.flatMap { item in
    return [item]
}
print(strings)

/// ["1", "2", "3"]

이 동작방식은 굉장히 유용합니다. 고차함수로 이루어진 코드일 경우 동기처리를 하고 싶을 때 하나의 Sequence로 이어줄 수 있습니다. 예시로, 카카오 API를 통해 auth code를 얻어와 해당 auth code를 이용해 다시 API를 호출하여 닉네임을 얻으려는 상황이 있습니다. 두 개의 API가 동기적으로 작동되어야할 때, flatmap을 통해 처리할 수 있습니다. (예시는 생략할게요) flatMap의 선언체를 보시면 더 이해하기 쉬울 것 같습니당 

 

다시 돌아와서 이 문제 또한 마찬가지로 [String]의 배열을 반환하기 때문에 flatmap을 사용하면 간단하게 코드를 작성할 수 있습니다.

풀이 코드 

Runtime 3ms | Memoty 14.7MB