코딩 테스트/프로그래머스
[Python] 프로그래머스 전화번호 목록
위시리
2024. 10. 8. 00:46
알고리즘 고득점 kit - 해시 - lv 2
문제분석
- 한 번호가 다른 번호의 접두어인가
- return
- 접두어인 경우 : false
- 접두어가 아닌 경우 : true
코드 설계
- 서로가 접두사인지 확인해야함
- phone_book에서 순서대로 비교할 문자열 빼기 (key)
- 해당 문자열이 접두사로 있으면 해당 key에 대한 value ++
- 전체 해시에서 value가 0이 아닌 key가 있다면 answer = false
정답 코드
실패..
다른 사람 코드 1 - 해시
def solution(phone_book):
answer = True
hash_map = {}
for phone_number in phone_book:
hash_map[phone_number] = 1
for phone_number in phone_book:
temp = ""
for number in phone_number:
temp += number
if temp in hash_map and temp != phone_number:
answer = False
return answer
- 초기 변수 설정 : 기본적으로 접두사 관계가 없다고 가정 나중에 접두사 관계가 발견되면 answer = False
- hash_map = {}로 전화번호를 저장할 해시 맵(딕셔너리) 생성
- 해시 맵에 전화번호 저장 : 첫 번째 for문을 통해 phone_book에 있는 모든 전화번호를 hash_map에 저장. 이 때, 각 전화번호를 키로 사용하고 값으로는 1 저장. 이 과정을 통해 각 전화번호가 해시 맵에 저장됨.
- 접두사 여부 확인 : 두 번째 for문은 다시 phone_book 리스트를 순회하면서, 각 전화번호에 대해 접두사 여부를 확인. temp라는 빈 문자열을 만들고, 그 전화번호의 각 숫자를 하나씩 더하면서 점진적으로 접두사를 만들어냄
- 각 단계에서 temp가 해시 맵에 존재하고, 그 값이 현재 확인 중인 전화번호(phone_number)와 동일하지 않다면, 접두사 관계가 있다는 의미 → answer를 False로 설정하고, 더 이상 확인할 필요 없이 종료
- 결과 반환
다른 사람 코드 2 - sort
def solution(phone_book):
answer = True
phone_book.sort()
for i in range(len(phone_book)-1):
if len(phone_book[i]) < len(phone_book[i+1]):
if phone_book[i + 1][:len(phone_book[i])] == phone_book[i]:
answer = False
break
return answer
- 만약에 어떤 번호가 다른 번호의 접두어라면 이 둘은 정렬했을 때 앞뒤에 위치하게 된다.
예를 들어 ["1235", "123", "12348", "012"]을 입력으로 받으면, sorted(["1235", "123", "12348", "012"])는 ["012", "123", "12348", "1235"]가 된다. - 따라서 phone_book을 정렬하고 for문을 이용해 phone_book[i]과 phone_book[i+1] 값을 비교했다.
첫번째 if문에서 i와 i+1의 길이를 비교한 것은 바로 아래의 if문에서 index가 out of range가 되는 것을 피하기 위함이다. - 효율성 테스트: ~105.76ms / 30.7MB
다른 사람 코드 3 - startswitch & zip
def solution(phoneBook):
phoneBook = sorted(phoneBook)
for p1, p2 in zip(phoneBook, phoneBook[1:]):
if p2.startswith(p1):
return False
return True
- zip
print(list(zip([1,2,3], (4,5,6), "abcd")))
### [[1, 4, 'a'], [2, 5, 'b'], [3, 6, 'c']]
- startswitch : 꽤 직관적인 함수로 p2가 p1으로 시작되면 True 아니면 False를 반환
print("dfagd".startswith("abcd"))
print("abcde".startswith("abcd"))
### False
### True