이번에 풀어본 문제는
프로그래머스 할인 행사 입니다.
import java.util.HashMap;
import java.util.Map;
classimport java.util.HashMap;
import java.util.Map;
class Solution {
public int solution(String[] want, int[] number, String[] discount) {
int answer = 0;
int wantLength = want.length;
int discountLength = discount.length;
Map<String, Integer> target = new HashMap<>();
for (int i = 0; i < wantLength; i++) target.put(want[i], number[i]);
Map<String, Integer> map = new HashMap<>();
// init
for (int i = 0; i < 10; i++) map.put(discount[i], map.getOrDefault(discount[i], 0) + 1);
// 초기값도 확인
if (check(target, map)) answer++;
for (int i = 1; i < discountLength - 9; i++) {
String previousKey = discount[i - 1];
int end = i + 9;
// start 제거
map.put(previousKey, map.getOrDefault(previousKey, 0) - 1);
if (map.get(previousKey) == 0) map.remove(previousKey);
map.put(discount[end], map.getOrDefault(discount[end], 0) + 1);
if (check(target, map)) answer++;
}
return answer;
}
static boolean check(Map<String, Integer> target, Map<String, Integer> map) {
for (String key: map.keySet()) {
if (!target.containsKey(key) || map.get(key) != target.get(key)) return false;
}
return true;
}
}
구매할 상품 총합이 10으로 고정되어있기 때문에, 길이 10의 연속된 할인 문자열이 모두 내가 사고싶은 상품으로 구성되어있어야 합니다.
모든 경우를 확인해야 하므로, 슬라이딩 윈도우를 활용했습니다.
한칸 씩 이동한다고 가정했을 때 한칸 이동한 후의 할인 문자열은 이전 기준 맨 앞 할인 상품을 제외하고, 증가된 길이의 마지막 할인 상품을 포함하면 됩니다.
이 규칙으로 윈도우를 한 칸씩 이동하며 모든 경우의 수와 target의 일치 여부를 판단하여 answer count를 증가시켜주면 해결할 수 있습니다.