반응형
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
다양한 종류의 보석들이 가게에 진열되어 있습니다. 당신은 모든 종류의 보석을 최소 한 개 이상 포함하는 가장 짧은 구간을 찾아야 합니다. 각 보석의 종류는 문자열로 주어지며, 이 문자열들의 배열이 주어질 때, 모든 보석을 포함하는 가장 짧은 구간을 구하는 문제입니다.
풀이 방법
이 문제는 슬라이딩 윈도우와 투 포인터 기법을 사용하여 해결할 수 있습니다. 기본 아이디어는 다음과 같습니다.
- 보석 종류 파악: 주어진 배열 gems에 있는 보석의 종류를 파악합니다.
- 슬라이딩 윈도우 초기화: 두 개의 포인터를 사용하여 현재 구간을 나타냅니다. 시작 포인터 start와 끝 포인터 end를 초기화합니다.
- 구간 확장: end 포인터를 이동시키며 모든 보석 종류를 포함할 때까지 구간을 확장합니다.
- 구간 축소 및 최적화: 모든 보석 종류를 포함하는 구간이 발견되면 start 포인터를 이동시키며 구간을 축소하고, 가장 짧은 구간을 찾습니다.
- 결과 반환: 가장 짧은 구간의 시작과 끝을 반환합니다.
정답 코드
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_set>
using namespace std;
vector<int> solution(vector<string> gems) {
// 보석의 종류를 저장할 unordered_set
unordered_set<string> gemKinds(gems.begin(), gems.end());
// 각 보석의 개수를 저장할 unordered_map
unordered_map<string, int> gemCount;
// 모든 종류의 보석 개수
int requireGemCnt = gemKinds.size();
int foundGemCnt = 0; // 현재 구간에서 찾은 보석의 종류 개수
int start = 0, end = 0; // 슬라이딩 윈도우의 시작과 끝
int min_start = 0, min_end = gems.size(); // 최소 구간의 시작과 끝
// 슬라이딩 윈도우 확장 및 축소
while (end < gems.size()) {
if (gemCount[gems[end]] == 0) {
foundGemCnt++;
}
gemCount[gems[end]]++;
end++;
// 모든 종류의 보석을 포함한 경우
while (foundGemCnt == requireGemCnt) {
// 현재 구간이 최소 구간보다 짧은지 확인
if (min_end - min_start > end - start) {
min_end = end;
min_start = start;
}
// start 포인터를 이동시켜 구간 축소
gemCount[gems[start]]--;
if (gemCount[gems[start]] == 0) {
foundGemCnt--;
}
start++;
}
}
// 결과 구간을 1-based index로 반환
return {min_start + 1, min_end};
}
반응형
LIST
'알고리즘 문제 > 프로그래머스' 카테고리의 다른 글
최고의 집합 [Lv. 3] (C++) (0) | 2024.08.03 |
---|---|
이중우선순위큐 [Lv. 3] (0) | 2024.07.23 |
경주로 건설 [Lv. 3] (C++) (0) | 2024.07.19 |
다단계 칫솔 판매 [Lv. 3] (C++) (1) | 2024.07.14 |
표 편집 [Lv. 3] (C++) (0) | 2024.07.12 |