[프로그래머스][해시] 전화번호 목록

sewonK·2021년 7월 26일
0

2. 전화번호 목록

내가 푼 풀이

def solution(phone_book):
    answer = True
    phone_book.sort()
    for i in range(0, len(phone_book) - 1):
        if(phone_book[i] == phone_book[i+1][0:len(phone_book[i])]):
            answer = False
            break
    return answer

기본적인 풀이 방법은 받은 phone_book을 정렬하고, 인접한 값끼리 서로 비교하면서 시간복잡도 N만에 푸는 방법이다. 풀이 방법은 그리 어렵지 않은데, 생각해내기 어려웠던 이유는 다음과 같다.

  1. 숫자 형태의 문자열을 정렬해야겠다는 생각이 안들었음.
  2. phone_book의 길이가 백만까지이기 때문에 이중 포문은 절대 안됨.

정렬 방법은 list.sort() 와 sorted(list) 가 있는데, 둘의 가장 큰 차이는 원본 리스트에 영향을 주는가? 이다.

list.sort()

a = [1, 2, 3]
a.sort(key=lambda x: x, reverse=True)
print(a)
>>> [3, 2, 1]

list.sort()는 원본 리스트 자체를 소팅한다. sort 내부 인자로 key 와 reverse를 줄 수 있다. key는 어떤 것을 기준으로 오름차순 할 것인지 정할 수 있고, 이 때 x: 기준 을 넣으면 된다. 기준에는 지금 예와는 맞지 않지만 (x[0], x[1]) 이런식으로 우선순위에 따라 여러 인자를 줄 수도 있다. reverse는 True로 설정할 경우 내림차순으로 변경된다.

sorted(list)

a = [1, 2, 3]
b = sorted(a, key=lambda x: x, reverse=True)
print(a)
>>> [1, 2, 3]
print(b)
>>> [3, 2, 1]

sorted(list)는 원본 리스트에 영향을 주지 않는다. 위의 결과처럼 원본인 a리스트는 변하지 않음을 알 수 있다. 나머지 인자들은 list.sort()와 같다.

Best 풀이

def solution(phoneBook):
    phoneBook = sorted(phoneBook)

    for p1, p2 in zip(phoneBook, phoneBook[1:]):
        if p2.startswith(p1):
            return False
    return True

여기서는 zip함수를 사용했다. 파이썬으로 문제를 풀 때마다 편리한 함수가 하나씩은 꼭 등장하는 것 같다.

zip 함수

zip 함수는 그룹의 데이터를 서로 엮어주는 파이썬의 내장 함수이다. zip() 함수는 여러 개의 순회 가능한(iterable) 객체를 인자로 받고, 각 객체가 담고 있는 원소를 튜플의 형태로 차례로 접근할 수 있는 반복자(iterator)를 반환한다.

phoneBook = ["119", "97674223", "1195524421"]
print(zip(phoneBook, phoneBook[1:]))
>>> <zip object at 0x000001E4E29B9208>

phoneBook = ["119", "97674223", "1195524421"]
for p1 ,p2 in zip(phoneBook, phoneBook[1:]):
    print(p1, p2)
>>> 119 97674223
>>> 97674223 1195524421

이렇게 보면 좀 더 쉬운데, zip 자체를 print했을 때는 이터레이터 객체가 반환되는 걸 알 수 있다. 그에 반해 해당 이터레이터를 통해 순회한 인자들을 print했을 때에는 값이 나온다. 여기서는 소팅을 안해주었지만, 문제 풀이에서는 문자열을 소팅한 이후 startswith 함수를 통해 접두어인지 아닌지 판별하고 있다. startswith 함수의 인자로는 튜플 또는 스트링 값이 올 수 있다.

0개의 댓글

관련 채용 정보