이것저것
[2020 카카오 인턴십] 보석 쇼핑 본문
https://programmers.co.kr/learn/courses/30/lessons/67258
[풀이과정]
구해야하는 것 : 보석을 모두 포함하는 가장 짧은 구간의 시작점과 종료점
1) 먼저 보석의 종류들을 set에 모두 담아둔다. (vector아닌 set에 담아두는 이유 : set은 중복 원소를 포함하지 않으므로, 보석이 종류들만 얻을 수 있다.
2) 투 포인터를 사용하여 가장 짧은 구간의 시작점을 찾아준다.
start와 end를 각각 0으로 초기화하고, 다음과 같은 두 가지의 경우로 나뉘어진다.
- 내가 현재까지 획득한 보석이 보석의 종류보다 적으면 end 를 증가
- 내가 현재까지 획득한 보석이 보석의 종류와 같다면 start를 증가 (같다면, set의 크기와 map의 크기가 같다.)
나는 이 획득한 보석을 map에 가장 최근 인덱스와 함께 저장해두었다.
start | end | |
0 | 0 (map에 아무값도 없으므로 map["DIA"] = 0, end++) | |
0 | 1 (map에 DIA만 있고 RUBY는 없으므로 map["RUBY"] = 1, end++) | |
0 | 2 (map에 DIA, RUBY 있는데, 또 RUBY 가 들어옴 : map["RUBY"] = 2로 업데이트하고, end++) | |
0 | 3 (map에 DIA, RUBY 있는데, 또 DIA 가 들어옴 : mp["DIA"] = 3으로 업데이트하고, end++) | |
0 | 4 (map에 DIA, RUBY 있는데, 또 DIA 가 들어옴 : mp["DIA"] = 5로 업데이트하고, end++) | |
0 | 5 (map에 DIA, RUBY 있는데, EMERALD 가 들어옴 : mp["EMERAD"] = 6, end++) | |
0 | 6 (map에 DIA, RUBY, EMERALD 있는데, SAPHIRE 가 들어옴 : mp["SAPHIRE"] = 7, end++) | |
모든 보석 다 채움 end - start = 7 - 1 = 6 |
0->1 (모든 종류의 보석을 남았으므로, start를 움직이기 시작, mp[gems[0(start)]] = mp["DIA"] = 5이므로, 그 값을 아직 지우진 말고, start ++) |
7 (이제 모든 종류의 보석을 담아 map의 크기와 set의 크기가 같아졌다.) |
모든 보석 다 채움 end - stat = 7 -2 =5 |
1->2 (gems[1] = RUBY, mp["RUBY"] = 2인데, 현재 start(1) 과 다르므로 건들지 않고, start ++) |
7 |
모든 보석 다 채움 end - start = 7-3 =4 |
2->3 (mp["RUBY"] = 2 = start 이므로, RUBY를 map에서 제거한다. 그리고 start++) |
7 |
3 | (방금 전에, map에서 RUBY를 뺏기 때문에 map에 DIA, EMERALD, SAPHIRE만 있다. mp["DIA"]는 이미 map에 존재한다.) | |
이제 end가 v의 배열에 끝 부분까지 검사했기 때문에 더 할 수 있는게 없으므로 while 문을 종료한다. |
투포인터가 진행되는 과정을 간단히 표와 글로 작성해보았다.
3) 모든 보석을 채우는 경우에 벡터에 넣어둔다.
4) 커스텀한 sort 옵션으로 문제의 조건에 맞게 정렬해주면 답을 구할 수 있다.
소스코드
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <iostream>
#include <set>
using namespace std;
bool compare(pair<int,int> p1,pair<int,int> p2){
int minus1 = p1.second - p1.first;
int minus2 = p2.second - p2.first;
if(minus1==minus2){
return p1.first < p2.first;
}else{
return minus1 < minus2;
}
}
vector<int> solution(vector<string> gems) {
vector<int> answer;
map<string,int> mp;
set<string> s;
for(int i=0;i<gems.size();i++){
s.insert(gems[i]);
}
int start = 0;
int end = 0;
vector<pair<int,int>> v;
while(1){
if(s.size()==mp.size()){
v.push_back({start,end});
if(mp[gems[start]]==start){
mp.erase(gems[start]);
}
start++;
}else if(end==gems.size()){
break;
}else{
mp[gems[end]]=end;
end++;
}
}
sort(v.begin(),v.end(),compare);
answer.push_back(v[0].first+1);
answer.push_back(v[0].second);
return answer;
}
'Problem Solving' 카테고리의 다른 글
[2021 KAKAO BLIND RECRUITMENT] 합동 택시 요금 (0) | 2021.04.15 |
---|---|
프로그래머스 Level3 베스트앨범 (1) | 2021.03.03 |
프로그래머스 Level3 N으로 표현 (0) | 2021.03.01 |
BOJ - 13549. 숨바꼭질 3 (0) | 2021.02.23 |
프로그래머스 Level2 - 멀쩡한 사각형 (0) | 2021.02.22 |
Comments