programmers.co.kr/learn/courses/30/lessons/67258
카카오 블로그의 해설과 질문하기 란을 보니 투포인터 방식으로 해결하라고 했다.
질문하기에서 어떤 분이 링크해주신 블로그 주소인데 깔끔하게 정리가 잘 돼 있어서 한번에 이해했다.
blog.naver.com/kks227/220795165570
vector<int> solution(vector<string> gems) {
vector<int> answer;
int gems_size = gems.size();
int min_dist = 100001;
unordered_map<string, int> list;
unordered_set<string> s_temp;
for (int i = 0; i < gems_size; ++i)
{
s_temp.insert(gems[i]);
}
int kind = s_temp.size();
int idx_r = 0, idx_l = 0;
while (1)
{
if (list.size() >= kind)
{
// 해당 key에 있는 value값을 하나 줄여준다.
list[gems[idx_l]]--;
if (list[gems[idx_l]] == 0)
{
// l의 포인터를 증가시킬 것이므로 지워준다.
list.erase(gems[idx_l]);
}
// 포인터 증가
idx_l++;
}
else if (idx_r == gems_size)
{
break;
}
else
{
list[gems[idx_r]]++;
idx_r++;
}
if (list.size() == kind)
{
int temp = idx_r - idx_l;
if (temp < min_dist)
{
answer.clear();
answer.push_back(idx_l + 1);
answer.push_back(idx_r);
min_dist = temp;
}
}
}
return answer;
}
그리고 다시 풀면서 한 번 헤맸던 부분이 있는데 min_dist의 초기값을 설정할 때 gems의 size보다 큰 값을 줘야 한다. 그러니까
gems의 size를 구해서 +1한 값을 주던지 아니면 gems는 최대 100000개가 들어올 수 있다고 했으니 그것보다 +1한 값을 설정해주거나. 그러지 않으면 r의 포인터값과 gem의 size를 비교해서 break를 하는 부분에서 마지막 부분에 break를 해버려 answer에 idx를 넣지 않는 경우가 발생한다. 구현방법은 여러가지이니까 다른 방식으로 구현했으면 상관없을 수도
바보 같은 그 전의 기록
이렇게 생각했던 이유는 vector나 list같은 컨테이너를 생각하며 데이터를 넣지 않으면 안들어가지 않나? 그럼 안에 데이터는 언제 채워넣어?ㅠ 내가 넣어주자ㅠ
라는 생각을 가지고 문제를 풀려고 했어서였다.
처음 문제 읽을 때 answer에 꽂혀서 분명 vector<int>형 반환임에도 string으로 들어온다고 [1, 1] 로 반환해야 되나? 하면서 10분을 고민했던 것과 같은 맥락이다.
진짜 여태 많은 오류를 만났지만 오늘같은 이런 신박한 뇌의 오류는 또 처음이다.
(미해결)이라고 포스팅한지 30분만에 뇌의 오류를 정정했다. 앞으로도 자주 써먹어야겠다.
vector<int> solution(vector<string> gems) {
vector<int> answer;
int gems_size = gems.size();
int min_dist = gems_size;
// 중복없는 unordered로
unordered_map<string, int> list;
unordered_set<string> s_temp;
for (int i = 0; i < gems_size; ++i)
{
s_temp.insert(gems[i]);
}
int kind = s_temp.size();
auto iter = list.begin();
int idx_r = 0, idx_l = 0;
if (kind == 1)
{
answer.push_back(1);
answer.push_back(1);
return answer;
}
while (idx_r < gems_size && idx_l < gems_size)
{
iter = list.find(gems[idx_r]);
if (iter != list.end())
{
iter->second += 1;
}
else
{
list.insert(pair<string, int>(gems[idx_r], 1));
}
if (list.size() < kind)
{
idx_r += 1;
}
else if (list.size() >= kind)
{
int temp = idx_r - idx_l;
if (temp < min_dist)
{
answer.clear();
answer.push_back(idx_l + 1);
answer.push_back(idx_r + 1);
min_dist = temp;
}
iter = list.find(gems[idx_l]);
iter->second -= 1;
if (iter->second == 0)
{
list.erase(iter);
}
idx_l += 1;
}
}
return answer;
}
이걸 어떻게 고쳐야 할까
문제 1. 보석의 종류를 어떻게 체크해야 될 지 감이 안와서 우선 set으로 (중복x) 넣어두고 size를 받아왔음.
근데 더 좋은 방법은 없나?
문제 2. 효율성 + 정확성 테스트 57.3 / 100. 어디가 문제인지 모르겠음
뭐가 문제일까 일단 올려두면 풀다 잊은 다른 문제들처럼 안 까먹을 것 같아서 올려둠.
혹시 지나가다가 이 난장판인 코드의 문제점을 아시는 분은 저에게 도움을 주세요
tech.kakao.com/2020/07/01/2020-internship-test/
카카오 블로그에 공식 해설이 있습니다!
'알고리즘 & 자료구조 > 프로그래머스' 카테고리의 다른 글
[C++/알고리즘] 프로그래머스 (프린터) (0) | 2020.09.10 |
---|---|
[C++/알고리즘] 프로그래머스 (문자열 압축) (0) | 2020.09.09 |
[C++/알고리즘] 프로그래머스 (크레인 인형 뽑기) (0) | 2020.09.03 |
[C++/알고리즘] 프로그래머스 (더 맵게) (0) | 2020.05.17 |
[C++/알고리즘] 프로그래머스 (탑) (0) | 2020.01.19 |