문제 링크 : programmers.co.kr/learn/courses/30/lessons/67258
이번 문제는 투포인터 문제다. 그냥 단순하게 모든 경우의 수 확인한다면 O(n^2)이 나올것이다.
하지만 투포인터를 이용하면 O(n)으로 해결할 수 있다.
<전체적인 알고리즘>
1. 보석을 set에 넣어서 보석 종류의 개수를 확인한다.
2. 투포인터(start , end)를 이용하여 증가시키며 확인한다.
2-1 투포인터 범위안에 보석종류가 포함안된게 있거나 start==end라면 end증가시켜 범위 늘리기
2-2 투포인터 범위안에 보석종류가 전부 포함되면 start 증가시키며 범위 축소해보기
3. 확인한 범위 중 최소의 범위 반환
<전체 코드>
#include<iostream>
#include <string>
#include <vector>
#include<set>
#include<map>
using namespace std;
vector<int> solution(vector<string> gems) {
set<string> s;
map<string,int> m;
map<string,int>::iterator iter;
for (int i = 0; i < gems.size(); i++)
{
s.insert(gems[i]); //보석종류 개수 알아보기
}
vector<int> answer{ 1,1 };
int start = 0;
int end = 0;
int minn = 987654321;
m.insert(make_pair(gems[0], 1)); // 처음 보석 삽입
if (m.size() == s.size())minn = 0; //보석 종류가 하나면 끝
while (1)
{
if (start == end || m.size() != s.size()) //투포인터 index가 같거나 포함안된 보석종류 있으면
{
end++;
if (end > gems.size() - 1)break;
m[gems[end]]++; //보석 삽입
}
else //보석 종류가 다 포함되면
{
if (end - start < minn) //지금까지 나온 범위중에 최소이면 index저장
{
minn = end - start;
answer[0] = start + 1;
answer[1] = end + 1;
}
iter = m.find(gems[start]);
iter->second--; //start포인터 이동시켜야 하니 그전 start보석 빼주기
if (iter->second == 0)m.erase(iter); //해당 보석이 0개가되면 보석종류 없애기
start++;
}
}
return answer;
}
궁금하신 점은 댓글에 남겨주시면 답변드리겠습니다.
반응형
'프로그래머스 코딩 문제 > 카카오 기출문제' 카테고리의 다른 글
[프로그래머스] GPS (2017 카카오코드 본선) (0) | 2020.11.04 |
---|---|
[프로그래머스] 리틀 프렌즈 사천성 (2017 카카오코드 본선) (1) | 2020.11.03 |
[프로그래머스] 방금그곡 (2018 KAKAO BLIND RECRUITMENT) (0) | 2020.09.10 |
[프로그래머스] 매칭 점수 (2019 KAKAO BLIND RECRUITMENT) (level 3) (0) | 2020.09.06 |
[프로그래머스] 기둥과 보 설치 (2020 KAKAO BLIND RECRUITMENT) (level 3) (0) | 2020.09.03 |