Programmers 1845 폰켓몬 (해시)
Programmers 1845 폰켓몬 (해시)
문제
폰켓몬 https://school.programmers.co.kr/learn/courses/30/lessons/1845
$N$마리의 폰켓몬 중 $N/2$마리를 선택할 때, 선택할 수 있는 가장 다양한 폰켓몬 종류의 수를 구하는 문제입니다.
nums배열의 길이 $N$: $2 \le N \le 10,000$- 폰켓몬 종류 번호: $1 \le \text{ID} \le 200,000$
복잡도 분석
- time complexity : $O(N)$
- 배열
nums를 한 번 순회하며 해시 자료구조(Map/Set)에 삽입하므로 $O(N)$이 소요됩니다.
- 배열
- space complexity : $O(N)$
- 최악의 경우 모든 폰켓몬의 종류가 다를 때, 해시 자료구조에 $N$개의 원소가 저장됩니다.
접근법
핵심은 ‘욕심쟁이 알고리즘(Greedy)’의 관점에서 접근하는 것입니다. 우리가 가질 수 있는 최대 종류는 다음 두 값 중 작은 값에 의해 결정됩니다.
- 물리적 한계: 우리가 뽑을 수 있는 최대 마릿수 ($N/2$)
- 자원적 한계: 배열에 존재하는 고유한 폰켓몬 종류의 수
풀이
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <vector>
#include <unordered_map>
using namespace std;
int solution(vector<int> nums) {
int answer = 0;
unordered_map<int, int> m;
for(const auto& e : nums) {
m[e]++;
}
// 종류의 수가 가질 수 있는 한도(size/2)를 넘으면 한도만큼,
// 아니라면 종류의 수만큼 반환
if(m.size() > nums.size() / 2) {
answer = nums.size() / 2;
} else {
answer = m.size();
}
return answer;
}
[개선된 코드 예시]
1
2
3
4
5
6
7
8
9
10
#include <vector>
#include <unordered_set>
#include <algorithm>
using namespace std;
int solution(vector<int> nums) {
unordered_set<int> s(nums.begin(), nums.end());
return min(s.size(), nums.size() / 2);
}
This post is licensed under CC BY 4.0 by the author.