-
[Programmers] 전화번호 목록[+] 알고리즘 [+] 2020. 4. 3. 15:29
[문제 설명]
전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다.
전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다.- 구조대 : 119
- 박준영 : 97 674 223
- 지영석 : 11 9552 4421
전화번호부에 적힌 전화번호를 담은 배열 phone_book 이 solution 함수의 매개변수로 주어질 때, 어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 그렇지 않으면 true를 return 하도록 solution 함수를 작성해주세요.
제한 사항
- phone_book의 길이는 1 이상 1,000,000 이하입니다.
- 각 전화번호의 길이는 1 이상 20 이하입니다.
[풀이 과정]
'접두어'라는 말에 살짝 이해하기 어려움이 있었지만 뜯어보면 생각보다 어렵지 않은 문제다.
phone_book 배열에 숫자로 이루어진 문자열이 여럿 있는데 어느 한 문자열의 앞부분이 다른 문자열을 완전히 포함하면 False를 리턴하면 된다.
def solution(phone_book): for i in range(0, len(phone_book)): for j in range(0, len(phone_book)): if i != j: if phone_book[i] == phone_book[j][:(len(phone_book[i]))]: return False return True
반복문을 이중첩으로 사용하여 구현하였다.
하지만 이보다 더 나은 풀이는 없을까?
문제를 풀고나서 다시 문제를 뜯어보며 더 나은 풀이를 생각해보기도 하고, 다른 방식으로 접근해보아야 실력이 느는법이지만...
필자는 인내심이 부족하여 문제를 풀고 바로 다음 문제로 넘어가는 경향이 있다.
이번만큼은 인내심을 갖고 다른 풀이를 생각하여보자!
def solution(phone_book): for string1 in phone_book: length = len(string1) for string2 in phone_book: if phone_book.index(string1) == phone_book.index(string2): continue if string2[:length] == string1: return False return True
아래의 방식으로도 풀어 보았다. 반복문에 인덱스 i 를 사용하는지 않는 방법이다.
하지만 phone_book.index()때문인걸까? 시간초과가 걸린다.
def solution(phone_book): phone_book = sorted(phone_book, key = lambda phone_book: len(phone_book)) for i in range(0, len(phone_book)-1): length = len(phone_book[i]) for j in range(i+1, len(phone_book)): if phone_book[i] == phone_book[j][:length]: return False return True
미리 phone_book 배열을 길이 순으로 정렬하여 탐색하였다.
길이가 더 짧은 문자열이 길이가 더 큰 문자열을 완전히 포함할 수는 없지 않은가?
이 생각에 착안하여 구현하였다.
효울성 테스트에서
테스트 1 〉 통과 (2.06ms, 15.3MB) 테스트 2 〉 통과 (1.89ms, 15.3MB) 테스트 1 〉 통과 (1.96ms, 15.3MB) 테스트 2 〉 통과 (1.91ms, 15.3MB) 이렇게 수행시간이 조금 변하긴 하였으나... 이게... 유의미한 차이인가?싶다...
'[+] 알고리즘 [+]' 카테고리의 다른 글
[Programmers] 탑 (0) 2020.04.04 [Programmers] 위장 (0) 2020.04.03 [Programmers] 멀쩡한 사각형 (0) 2020.03.20 [Programmers] 종이접기 (0) 2020.03.18 [Programmers] 방문 길이 (0) 2020.03.12