14. 프로그래머스 - 폰켓몬 (해시)

2025. 7. 29. 12:33·코딩 테스트 준비/문제

문제 설명

당신은 폰켓몬을 잡기 위한 오랜 여행 끝에, 홍 박사님의 연구실에 도착했습니다. 홍 박사님은 당신에게 자신의 연구실에 있는 총 N마리의 폰켓몬 중에서 N/2마리를 가져가도 좋다고 했습니다.

홍 박사님 연구실의 폰켓몬은 종류에 따라 번호를 붙여 구분합니다. 따라서 같은 종류의 폰켓몬은 같은 번호를 가지고 있습니다. 예를 들어 연구실에 총 4마리의 폰켓몬이 있고, 각 폰켓몬의 종류 번호가 [3, 1, 2, 3]이라면 이는 3번 폰켓몬 두 마리, 1번 폰켓몬 한 마리, 2번 폰켓몬 한 마리가 있음을 나타냅니다.

이때, 4마리의 폰켓몬 중 2마리를 고르는 방법은 다음과 같이 6가지가 있습니다.

  1. 첫 번째(3번), 두 번째(1번) 폰켓몬을 선택
  2. 첫 번째(3번), 세 번째(2번) 폰켓몬을 선택
  3. 첫 번째(3번), 네 번째(3번) 폰켓몬을 선택
  4. 두 번째(1번), 세 번째(2번) 폰켓몬을 선택
  5. 두 번째(1번), 네 번째(3번) 폰켓몬을 선택
  6. 세 번째(2번), 네 번째(3번) 폰켓몬을 선택

이때, 첫 번째(3번) 폰켓몬과 네 번째(3번) 폰켓몬을 선택하는 방법은 한 종류(3번 폰켓몬 두 마리)의 폰켓몬만 가질 수 있지만, 다른 방법들은 모두 두 종류의 폰켓몬을 가질 수 있습니다. 따라서 위 예시에서 가질 수 있는 폰켓몬 종류 수의 최댓값은 2가 됩니다.

당신은 최대한 다양한 종류의 폰켓몬을 가지길 원하기 때문에, 최대한 많은 종류의 폰켓몬을 포함해서 N/2마리를 선택하려 합니다.

N마리 폰켓몬의 종류 번호가 담긴 배열 nums가 매개변수로 주어질 때, N/2마리의 폰켓몬을 선택하는 방법 중, 가장 많은 종류의 폰켓몬을 선택하는 방법을 찾아, 그때의 폰켓몬 종류 번호의 개수를 return 하도록 solution 함수를 완성해주세요.


제한사항

  • nums는 폰켓몬의 종류 번호가 담긴 1차원 배열입니다.
  • nums의 길이(N)는 1 이상 10,000 이하의 자연수이며, 항상 짝수로 주어집니다.
  • 폰켓몬의 종류 번호는 1 이상 200,000 이하의 자연수로 나타냅니다.
  • 가장 많은 종류의 폰켓몬을 선택하는 방법이 여러 가지인 경우에도, 선택할 수 있는 폰켓몬 종류 개수의 최댓값 하나만 return 하면 됩니다.

입출력 예

numsresult
[3,1,2,3] 2
[3,3,3,2,2,4] 3
[3,3,3,2,2,2] 2
 

입출력 예 설명

  • 예 #1
    문제의 예시와 같습니다.
  • 예 #2
    6마리의 폰켓몬이 있으므로 3마리를 선택해야 합니다.
    가능한 최대 종류는 3번, 2번, 4번 폰켓몬을 하나씩 선택하여 3종류입니다.
  • 예 #3
    6마리의 폰켓몬이 있으므로 3마리를 선택해야 합니다.
    3번 폰켓몬과 2번 폰켓몬밖에 없으므로 최대 2종류를 선택할 수 있습니다.

문제 접근 

- 동일한 폰켓몬은 같은 번호를 가지고 있다 -> Set은 중복을 허용하지 않으므로 Set을 이용하면된다. Set 중에 어떤 Set을 이용하면 좋을까??

- 바로 HashSet이다. 이유는 문제에서 가능한 많은 서로 다른 종류의 폰켓몬을 선택하는 문제이므로 HashSet을 사용하면 중복을 허용하지 않고 빠르게 계산할 수 있다.

 

 Set<Integer> set = new HashSet<>();
        
for (int num : nums) {
    set.add(num);
}

set 객체를 생성하고 for문을 돌리면서 set에 넣어준다. 이러면 동일한 폰켓몬은 알아서 걸러지게 된다.

 

종류 수가 고를 수 있는 마릿수보다 많다면 그만큼만 고를 수 있으므로 Math.min을 이용해서 구하면 쉽게 구할 수 있다.

int maxPick = nums.length / 2;
        
return Math.min(set.size(), maxPick);

 

 

알고리즘 코드

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

class Solution {
    public int solution(int[] nums) {
        Set<Integer> set = new HashSet<>();
        
        for (int num : nums) {
            set.add(num);
        }
        
        int maxPick = nums.length / 2;
        
        return Math.min(set.size(), maxPick);
    }
}

 

 

시간 복잡도 분석

  • nums 배열을 한 번 순회 → O(N)
  • 각 add() 연산은 HashSet 기준 평균 O(1)
    (충돌이 거의 없고, 해시 충돌 방지가 잘 되어 있다는 전제 하에)

따라서 이 루프 전체는 O(N)이다.

'코딩 테스트 준비 > 문제' 카테고리의 다른 글

16. 프로그래머스 - 체육복 (그리디)  (2) 2025.08.04
15. 프로그래머스 - 디스크 컨트롤러 (힙)  (3) 2025.08.04
13. 프로그래머스 - 더 맵게 (힙)  (1) 2025.07.28
12. 프로그래머스 - 주식 가격 (스택)  (2) 2025.07.28
11. 프로그래머스 - 오픈 채팅방(해시)  (2) 2025.07.21
'코딩 테스트 준비/문제' 카테고리의 다른 글
  • 16. 프로그래머스 - 체육복 (그리디)
  • 15. 프로그래머스 - 디스크 컨트롤러 (힙)
  • 13. 프로그래머스 - 더 맵게 (힙)
  • 12. 프로그래머스 - 주식 가격 (스택)
masxer
masxer
masxer 님의 블로그 입니다.
  • masxer
    masxer 님의 블로그
    masxer
  • 전체
    오늘
    어제
    • 분류 전체보기 (54)
      • 알고리즘 (7)
      • 코딩 테스트 준비 (34)
        • 문제 (28)
        • 개념 (6)
      • 25-1 여름방학 공모전 프로젝트 (0)
      • 스프링부트 (6)
      • 도커 (5)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
masxer
14. 프로그래머스 - 폰켓몬 (해시)
상단으로

티스토리툴바