개발자 월든
월든의 더 나은 개발하기
개발자 월든
전체 방문자
오늘
어제
  • 분류 전체보기 (17)
    • Web 개발 관련 지식 (1)
    • 웹 백엔드 프레임워크 (1)
      • FastAPI (1)
      • Spring (0)
    • 웹 프론트엔드 (0)
      • HTML (0)
      • CSS (0)
      • Vanilla JS (0)
      • React (0)
    • 데이터베이스 (2)
      • MySQL (1)
      • Cache (0)
    • 인프라 자동화 (2)
      • Docker (1)
      • kubernetes (0)
      • Jenkins (1)
    • 객체 지향 프로그래밍 (0)
    • 도메인 주도 설계 (0)
    • 마이크로서비스 아키텍쳐 (0)
    • 시스템 설계 (2)
    • 프로그래밍 언어 (6)
      • Java (6)
      • Python (0)
      • Javascript (0)
    • 알고리즘 문제풀이 (2)
      • C++ (0)
      • Java (2)
    • 컴퓨터 공학 전공 (0)
    • 개발 관련 도구 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • JCP #JSR # TCK

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
개발자 월든

월든의 더 나은 개발하기

알고리즘 문제풀이/Java

[프로그래머스] 전화번호 목록 in JAVA

2021. 8. 8. 23:47

개요

프로그래머스 고득점 Kit에서 level 2인 전화번호 목록 문제입니다. 이 문제의 유형은 해시맵으로 key, value로 이루어진 해시맵 자료구조를 활용해야한다는 힌트가 주어집니다.

 

문제의 요구사항은 전화번호가 적힌 문자열 배열에서 어느 한 전화번호가 다른 전화번호의 접두어일 경우를 찾는 것입니다. 중복되는 문자열은 존재하지 않습니다.

 

* 119의 접두어로는 1, 11이 있습니다.

모든 값을 순회하는 해결

public boolean solution2(String[] phone_book) {

    for (int i = 0; i < phone_book.length; i++) {
      for (int j = 0; j < phone_book.length; j++) {
        if (i == j) { continue; }
        if (phone_book[i].startsWith(phone_book[j])) { return false; }
        if (phone_book[j].startsWith(phone_book[i])) { return false; }
      }
    }
    
    return true;
  }

 

이중 반복문을 사용하여 모든 값을 순회하여 비교하는 단순한 방법입니다. 구현하기에 직관적이지만 시간복잡도가 O(n^2)인 한계가 있습니다. 실제로 이 답안을 제출하면 효율성 테스트에서 실패하는 모습을 볼 수 있습니다.

해시를 활용한 해결

public boolean solution(String[] phone_book) {
    HashSet<String> hashSet = new HashSet<>(Arrays.asList(phone_book));

    for (String str: phone_book) {
      for (int i = 0; i < str.length(); i++) {
        String temp = str.substring(0, i);
        if (hashSet.contains(temp)){
          return false;
        }
      }
    }
    return true;
  }

 

phone_book 문자열 배열을 hashSet에 입력합니다. 이때 HashMap이 아니라 HashSet인 것은 key, value 중 value 값은 사용되지 않기 때문입니다. 

 

주어진 전화번호 목록 phone_book을 순회하면서 전화번호의 0~1번째 글자가 해시셋에 존재하는지 확인, 0~2번째 글자가 해시셋에 존재하는지 확인을 하면서 정답을 찾아가는 방식입니다. 쉽게 말하면 배열과 배열을 비교하는 것은 모든 배열을 순회해야하는 것을 해시셋으로 변경하여 빠르게 찾을 수 있도록 한 것입니다. 이는 hashSet은 검색이 빠르다는 장점을 활용한 것입니다. 

 

배열을 이용한 해결처럼 똑같은 이중 반복문을 사용하기 때문에 효율성에서 큰 차이가 없을 것처럼 보이기도 합니다. 하지만 이중 반복문이긴 하지만 반복하는 전화번호 값은 전화번호 개수와 상관없이 최대 20글자이기 때문에 최악의 경우 O(nm), m은 <= 20으로 보여져 O(n^2)보다는 훨씬 빠릅니다. 또한 hashSet에서 값을 찾아내는 것도 O(1)이기 때문에 이 부분에서도 효율성에 문제가 없습니다. 

 

배운 점

1. 어떠한 값을 빨리 찾아내야할 때(검색) HashMap 자료구조를 사용하면 좋다.

2. HashMap 자료구조를 사용할 때 value가 필요 없을 경우 HashSet을 사용한다.

3. startsWith는 문자열의 접두어인지를 알려주는 메소드이다.

 

'알고리즘 문제풀이 > Java' 카테고리의 다른 글

[프로그래머스] 완주하지 못한 선수 in JAVA  (0) 2021.08.03
    '알고리즘 문제풀이/Java' 카테고리의 다른 글
    • [프로그래머스] 완주하지 못한 선수 in JAVA
    개발자 월든
    개발자 월든
    백엔드 개발자 월든의 개발 관련 포스팅을 올리는 공간입니다. 출처가 불명확한 정보, 요령, 대충 넘어가기 보다 꼼꼼하고 정확하고 기본에 가까운 정보를 드리려고 노력하고 있습니다.

    티스토리툴바