STUDY/알고리즘
[프로그래머스] 전화번호 목록 (Python)
seonyounggg
2021. 4. 9. 22:16
✏️ 문제
코딩테스트 연습 - 전화번호 목록
전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다. 전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다. 구조
programmers.co.kr
✏️ 풀이
문제 분류가 Hash라는 것을 알고 풀어서, 처음부터 딕셔너리를 사용하는 방법으로 접근했다.
phone_book의 모든 원소는 접두어 후보이므로 딕셔너리에 dict[접두어] = True 를 넣는다.
이후 다시 phone_book을 탐색한다.
이 때, 한 전화번호를 "한글자 ~ 길이-1" 만큼 잘라서 해당 값을 인덱스로 가지는 원소가 dict에 있는 지 살펴본다.
만약 있다면 접두어가 존재한다는 뜻이므로 바로 False를 리턴한다.
dict에 있는지 살펴볼 때 KeyError를 피하기 위해 defaultdict를 사용하였다.
✏️ 코드
from collections import defaultdict
def solution(phone_book):
dict = defaultdict(bool)
for num in phone_book:
num = num.replace(" ", "")
dict[num] = True
for num in phone_book:
num = num.replace(" ", "")
for s in range(1, len(num)):
if dict[num[0:s]] == True:
return False
return True
처음에는 dict에 넣으면서 검사도 동시에 했는데 테스트케이스 20개 중 3개가 실패했다.
앞쪽 원소의 접두어가 뒷부분에 나오는 예외는 커버하지 못한다는 것을 깨닫고 반복문 2개로 분리했다.
from collections import defaultdict
def solution(phone_book):
dict = defaultdict(bool)
phone_book.sort()
for num in phone_book:
for s in range(1, len(num)+1):
if dict[num[0:s]] == True:
return False
dict[num] = True
return True
위에서 언급한 예외를 정렬을 통해 커버할 수 있었다. (1234 123 이 있으면 123이 먼저 나오게 될테니까)
그러나 시간이 현저히 오래걸렸다.
✏️ 다른 사람 풀이
def solution(phoneBook):
phoneBook = sorted(phoneBook)
for p1, p2 in zip(phoneBook, phoneBook[1:]):
if p2.startswith(p1):
return False
return True
해쉬를 이용하지 않은 다른 풀이다. zip이라는 함수를 새롭게 알게되었다.