코딩 테스트 준비/문제

18. 프로그래머스 - 전화번호 목록(해시)

masxer 2025. 8. 6. 20:57

문제: 전화번호 목록에서 접두어 확인

전화번호부에 적힌 전화번호 목록이 주어집니다. 이 목록에서 어떤 번호가 다른 번호의 접두어(prefix) 인 경우가 있는지 확인하려고 합니다.

예를 들어, 다음과 같은 전화번호 목록이 있다고 가정합니다.

  • "119"
  • "1195524421"
  • "97674223"

이 경우 "119"는 "1195524421"의 접두어이므로, 조건을 만족하지 않습니다.


목표

전화번호부에 있는 번호 중 어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 반환하고,
그렇지 않으면 true를 반환하는 함수를 작성하세요.


입력

  • phone_book: 문자열 배열
  • 전화번호의 개수는 1 이상 1,000,000 이하
  • 각 전화번호의 길이는 1 이상 20 이하
  • 전화번호는 중복되지 않음

출력

  • true 또는 false
  • true: 어떤 번호도 다른 번호의 접두어가 아님
  • false: 어떤 번호가 다른 번호의 접두어임

입출력 예시

 

phone_book return
["119", "97674223", "1195524421"] false
["123","456","789"] true
["12","123","1235","567","88"] false
 

설명

  • 첫 번째 예시에서는 "119"가 "1195524421"의 접두어이므로 false를 반환합니다.
  • 두 번째 예시에서는 어떤 번호도 다른 번호의 접두어가 아니므로 true를 반환합니다.
  • 세 번째 예시에서는 "12"가 "123"의 접두어이므로 false를 반환합니다.

 


전화번호 목록 phone_book 중, 어떤 번호가 다른 번호의 접두어인 경우가 있는지 확인한다.

전화번호의 접두어가 존재하는지 빠르게 확인하기 위해 HashSet을 사용한다.

 

List O(n) 순서가 중요하거나 전체 순회가 필요할 때
Set O(1) 특정 값 존재 여부를 빠르게 확인할 때

 

표와 마찬가지로 리스트로 정렬해서 접두사가 같은지 비교하면 될 것 같지만 phone_book의 길이는 1 이상 1,000,000 이하라는 제한 사항이 존재하기 때문에 List보다 Set을 사용하는게 좋다.

 

따라서 우리가 접근할 수 있는 방법은 아래와 같다.

 

  • phone_book의 모든 번호를 HashSet에 넣는다.
  • 각 번호에 대해, 접두어 후보들을 만들어서 그 접두어가 Set에 있는지 확인한다.
    • 예: "12345" → 접두어 후보: "1", "12", "123", "1234"
  • 만약 접두어가 Set에 존재한다면, 다른 전화번호의 접두어이므로 false 반환

 

알고리즘 코드

 

import java.util.Set;
import java.util.HashSet;

class Solution {
    public boolean solution(String[] phone_book) {   
        Set<String> phoneSet = new HashSet<>();
        
        for(String num : phone_book) {
            phoneSet.add(num);
        }
        
        
        for (String num : phone_book) {
            for(int i = 1; i < num.length(); i++) {
                String prefix = num.substring(0, i);
                if(phoneSet.contains(prefix)) {
                    return false;
                }
            }
        }
        
        return true;
    }
}

 

 

 

시간 복잡도 분석

각 번호 길이를 k라 하면, prefix는 k - 1개 생성되고 각 prefix에 대해 set.contains() → 평균 O(1)이므로 한 번호당

O(k), 전체 n개 이므로 전체 시간 복잡도는 O(n * k)이다.