파게로그
[프로그래머스 Lv.3] 보석 쇼핑 본문
문제 링크: 프로그래머스 Lv. 3 보석 쇼핑
https://programmers.co.kr/learn/courses/30/lessons/67258
투 포인터를 통해 해결할 수 있는 문제이다.
left
와 right
를 움직여주면서 [left, right]
구간 내에 모든 보석이 1개 이상 포함된다면, 이 때 시작 진열대 번호
와 끝 진열대 번호
를 갱신한다.
이러한 과정에서 left
와 right
는 다음과 같이 움직인다.
구간 내에 모든 보석이 포함되어 있다면? 이 때에는 크기를 줄여본다. 즉 left
를 1 증가시킨다.
구간 내에 모든 보석이 포함되어 있지 않다면? 이 때에는 더 많은 보석을 보아야 한다. 즉 right
를 1 증가시킨다.
한편 구간 내에 모든 보석이 포함되어 있는지의 여부에 대해서는 어떻게 알 수 있을까? gems
배열의 크기는 1 이상 100,000 이하라고 했으므로 O(n)으로 해결되어야 한다. 다시말해 left
나 right
를 옮길 때마다 구간을 순회하면서 확인하는 O(n^2)의 방법은 이용하지 못한다.
이를 위해 각 보석의 개수인 int[] count
와, 포함된 보석의 종류 int included
를 이용할 수 있다. 각 보석의 크기를 count
에 보관하되, left
를 움직여서 특정 보석이 제외될 때(count[i]
의 값이 1에서 0이 될 때) 또는 right
를 움직여서 특정 보석이 추가될 때(count[i]
의 값이 0에서 1이 될 때)에는, included
를 각각 감소시키거나 증가시키는 것이다.
map을 이용하여 key에는 보석, value에는 보석의 개수를 두고 map의 크기를 확인함으로써 included
를 대체할 수도 있으나, 조금 더 C 스타일에 가까운 전자의 방법이 범용적일 것이다.
import java.util.*;
class Solution {
static int numGemType = 0;
static int numGemShow = 0;
static Map<String, Integer> map = new HashMap<>();
static int answerLen = Integer.MAX_VALUE;
static int answer1 = -1;
static int answer2 = -1;
public int[] solution(String[] gems) {
init(gems);
int left = 0;
int right = 0;
// while문 진입 시 이미 [left, right] 구간에 대한 탐색이 완료되었다고 가정하므로
// while문 진입 이전에 초기값 세팅이 필요하다.
// 또는 left = -1, right = -1로 설정하는 방법이 있다.
int[] count = new int[numGemType];
int included = 1;
count[map.get(gems[0])]++;
while (true) {
if (included == numGemType) {
if (right - left + 1 < answerLen) {
answerLen = right - left + 1;
answer1 = left;
answer2 = right;
}
count[map.get(gems[left])]--;
if (count[map.get(gems[left])] < 1) included--;
left++;
} else {
right++; if (right >= numGemShow) break;
if (count[map.get(gems[right])] < 1) included++;
count[map.get(gems[right])]++;
}
}
return new int[]{answer1+1, answer2+1};
}
static void init(String[] gems) {
numGemShow = gems.length;
int idx = 0;
for (String g : gems) {
if (!map.containsKey(g)) {
map.put(g, idx);
idx++;
}
}
numGemType = map.size();
}
}
'콤퓨타 왕왕기초 > PS' 카테고리의 다른 글
[백준 13334번] 철로 (0) | 2021.09.12 |
---|---|
[백준 1967번] 트리의 지름 (0) | 2021.09.09 |
[백준 21316번] 스피카 (0) | 2021.08.14 |
[백준 12865] 0-1 Knapsack Problem (0) | 2021.07.26 |
[백준 17840번] 피보나치 음악 (0) | 2021.05.06 |