Coding Test Practice/프로그래머스

프로그래머스 Level2, 전화번호 목록, python

still..epochs 2022. 12. 12. 22:33

문제 설명

전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다.
전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다.

  • 구조대 : 119
  • 박준영 : 97 674 223
  • 지영석 : 11 9552 4421

전화번호부에 적힌 전화번호를 담은 배열 phone_book 이 solution 함수의 매개변수로 주어질 때, 어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 그렇지 않으면 true를 return 하도록 solution 함수를 작성해주세요.

제한 사항
  • phone_book의 길이는 1 이상 1,000,000 이하입니다.
    • 각 전화번호의 길이는 1 이상 20 이하입니다.
    • 같은 전화번호가 중복해서 들어있지 않습니다.

 

문제풀이

처음 문제를 풀이할 때, phone_book 리스트를 정렬을 실행한 후 2중 for 문으로 풀이를 시도 하였다. 코드는 다음과 같다.

# 틀린 풀이
def solution(phone_book):
	phone_book.sort()
    
    for i in range(len(phone_book)):
        for j in range(i+1, len(phone_book)):
            if phone_book[i] in phone_book[j]:
                return False
    else:
        return True

 

sort()

먼저 phone_book 리스트를 정렬 해 준다. ["119", "97674223", "1195524421"]  이 리스트로 보면 정렬이 ["119", "1195524421", "97674223"] 과 같이 길이가 짧은 문자열 기준으로 다음 문자열 앞에 중복되는 문자열이 있다면 그 순서대로 정렬이 된다. 이렇게 되면 인덱스 0번째와 1번째를 비교하면 0번째 문자열이 그 뒤 문제열의 접두어 인지 판별할 수 있다.

 

예제 문제는 통과하였으나, 정답 제출에서 틀린 부분과 효율성 테스트 실패가 떠서 다시 풀이를 시도하였다.

 

def solution(phone_book):
    phone_book.sort()
    
    for i, j in zip(phone_book, phone_book[1:]):
        if j.startswith(i):
            return False
    return True

내가 기존에 접근했던 방식과 비슷하나 코드는 완전히 다르다. 

 

zip()

zip은 각 리스트의 요소들을 인덱스 순서에 맞춰 반환해 주는 메서드다.

a = [1, 2, 3]
b = [4, 5, 6]

for i, j in zip(a, b):
	print(i, j)
    
>>  1 4
    2 5
    3 6

 

startswith()

이 메서드는 해당 문자열의 시작이 특정 문자열로 시작되는지 확인 할 수 있는 메서드다.

이를 이용해서 정렬시킨 phone_book 과 phone_book[1:] 의 자리를 각각 비교하면서 True, False 값을 반환 해 준다.

phone_book = ["12","123","1235","567","88"]

phone_book.sort()
    
for i, j in zip(phone_book, phone_book[1:]):
    print(i,j)
    

>>  12 123
    123 1235
    1235 567
    567 88

이렇게하면 2중 for 문을 사용하지 않고 앞 뒤의 문자열을 비교할 수 있다.

 

코딩 테스트는 끝이 존재하는 공부라고 한다. 아직 모르는게 너모 많자너..