[프로그래머스] [카카오 인턴]보석 쇼핑
프로그래머스의 Lv.3 [카카오 인턴]보석쇼핑입니다.
문제 출처
문제 해설
우선 문제의 조건을 보자.
gems 배열의 크기는 1 이상 100,000 이하입니다.
이 조건을 봤을 때, 시간복잡도가 n^2를 넘어간다면, 연산 수는 100,000,000,000으로 절대로 시간 내에 풀 수 없다. 그렇기 때문에 시간 복잡도를 가능한 nlogn 이하로 내려야 한다. 이 점을 생각하면서 문제를 풀어보자.
결국 문제는 모든 종류의 보석을 적어도 1개 이상 포함하는 연속되면서 가장 짧은 구간을 구하는 것이다.
내가 생각한 해결 방법은
- gems에 어떤 보석들이 있는지 구하기 위해서, HashSet을 생성해서, gems를 순회하면 HashSet에 넣는다.
- <string, int>를 가지는 HashMap을 생성한다. String은 gems의 이름, int는 현재 HashMap에 들어가 있는 gems의 개수이다.
- gems를 처음부터 돌면서, HashMap에 값이 없다면, HashMap에 값을 넣는다.
- HashMap의 크기가 HashSet의 크기와 같다면, 현재 문제가 요구하는 조건을 찾은 것이다. 이를 결과 벡터에 저장한다.
- HashMap의 처음 부분부터 인덱스를 증가시켜가며, HashMap에서 해당 값들을 하나씩 지운다.
- HashMap의 int 값이 0이 되면 해당 key값을 HashMap에서 삭제한다. 이후 break한다.
- HashMap의 크기가 HashSet의 크기보다 작아지면, 문제가 요구하는 조건을 만족하지 않음으로 다시 gems를 돌기 시작한다.
- 작이지기 전까지는 항상 조건을 만족함으로 결과 벡터에 저장한다.
- gems의 끝에 도달하면 반복문을 break한다.
- gems를 처음부터 돌면서, HashMap에 값이 없다면, HashMap에 값을 넣는다.
- 결과들은 결과 벡터에 저장되어 있음으로, 결과 벡터에서 가장 범위가 작은 값을 return 한다.
이렇게 풀면 최대 O(N)안에 문제를 해결 할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <bits/stdc++.h>
using namespace std;
unordered_set<string> h_Set;
unordered_map<string, int> h_Map;
vector<int> solution(vector<string> gems) {
vector<vector<int>> answer;
for(auto a : gems)
h_Set.insert(a);
int MaxNum = h_Set.size();
int aP = 0; int bP = 0;
for(int i=0;i<gems.size();++i){
++bP;
h_Map[gems[i]]++;
if(h_Map.size() == MaxNum){
while(true){
if(h_Map[gems[aP]] == 1){
h_Map.erase(gems[aP]);
vector<int> temp;
temp.push_back(++aP);
temp.push_back(bP);
answer.push_back(temp);
break;
}else{
h_Map[gems[aP]]--;
++aP;
}
}
}
}
int answerCount = 1000000;
int answerCheck = -1;
for(int i=0;i<answer.size();++i){
int temp = answer[i][1] - answer[i][0];
if(answerCount > temp){
answerCount = temp;
answerCheck = i;
}
}
return answer[answerCheck];
}
This post is licensed under CC BY 4.0 by the author.