[프로그래머스] 전화번호 목록
[프로그래머스] 전화번호 목록
▪︎ 문제
▪︎ 알고리즘 설계
- Sorting / Loop 활용
- 전화번호를 오름차순으로 정렬한다.
- 예를들어,
phone_book[0] = “12”
,phone_book[1] = “6”
,phone_book[2] = “6789”
라고 하자. - 0번 인덱스의 값이 1번 인덱스의 값의 접두어가 될 수 있는 경우는 있지만, 0번 인덱스의 값이 1번 인덱스의 값의 접두어가 아닐 경우, 0번 인덱스의 값이 2번 인덱스의 값의 접두어가 될 수 있는 경우는 없다.
- 그리고, 2번 인덱스의 값이 1번 인덱스의 값의 접두어가 될 수 있는 경우가 없다.
- 따라서 정렬을 하면 인접한 두 숫자만 비교하면 되고, 앞의 숫자가 뒤의 숫자의 접두어인지만 비교하면 된다.
- 예를들어,
- 한 번의 루프만 돌면서 두 개의 숫자를 비교한다.
- 앞의 숫자가 뒤의 숫자의 접두어인지 확인하면 정답을 구할 수 있다.
- 전화번호를 오름차순으로 정렬한다.
- Hash 활용
- key에 선수 이름, value에 count를 갖는 해시 맵을 만든다.
- completion에 존재하는 선수들의 해시를 뺀다.
- value가 남아있는 선수가 완주하지 못한 선수이다.
▪︎ 코드
Sorting / Loop 활용
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
import java.util.*; class Solution { public boolean solution(String[] phone_book) { Arrays.sort(phone_book); for(int i = 0; i < phone_book.length - 1; i++) { if(phone_book[i+1].startsWith(phone_book[i])) { return false; } } return true; } }
Hash 활용
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
import java.util.*; class Solution { public boolean solution(String[] phone_book) { HashMap<String, Integer> map = new HashMap<>(); for(int i = 0; i < phone_book.length; i++) { map.put(phone_book[i], 1); // value 값은 그냥 '전화번호가 1개 존재'라는 의미 } for(int i = 0; i < phone_book.length; i++) { for(int j = 1; j < phone_book[i].length(); j++) { // phone_book[i]의 길이보다 1번 작게 검토 (같은 전화번호는 없기 때문에!) if(map.containsKey(phone_book[i].substring(0, j))) return false; } } return true; } }
▪︎ 시간복잡도
- Sorting / Loop 활용:
O(N log N + N·M)
- Hash 활용:
O(N·M)
▪︎ 틀린 이유
- 정렬을 사용했을 때
substring
으로 구현했더니, 뒤의 값보다 앞의 값이 길 때endIndex
가 범위를 넘어StringIndexOutOfBoundsException
발생.- 해결:
startsWith
는 자동으로 길이를 체크해 안전. - 또는
substring
사용 시 길이 조건을 먼저 확인해야 함.
- 해결:
- HashMap 풀이 시
value
를 전화번호 길이로 저장해도 의미가 없으며, 단순히 존재 여부만 필요하므로 값은 상징적인1
만 사용. - HashMap 풀이를 처음 생각할 때 모든 접두어를 확인하는 이중 반복문 + containsKey + substring 조합을 떠올리지 못했음.
▪︎ 느낀점 / 기억할 정보
- 문자열 처리 시 substring은 항상 인덱스 범위를 고려해야 한다.
endIndex
>length
→StringIndexOutOfBoundsException
.- 안전하게 처리하고 싶으면
startsWith
같은 메서드 사용.
- HashMap을 사용할 때 value 값은 중요하지 않을 수 있다.
- 존재 여부 확인에는 key만 필요.
- key 탐색은 평균 O(1)이므로 빠름.
- 접두어 문제에서 자주 쓰이는 패턴
- 정렬 후 인접 비교
- 해시맵에 전체 문자열 저장 후 접두어를 하나씩 검사
This post is licensed under CC BY 4.0 by the author.