슬라이딩 윈도우는 창문이 열리듯 같은 범위를 유지하며 한 칸씩 이동하면서 값을 찾는 알고리즘이다.
이 문제는 초기 구간을 설정한 뒤 한 칸씩 이동을 하며 값을 찾으면 되는 문제이다.
0부터 P까지 반복문을 돌며 초기 문자열이 비밀번호에 부합하는지 확인 후
한 칸씩 이동하며 값을 찾아내면 된다.
초기 최소 개수를 설정을 해줄 때에 최소 개수가 0이면 count를 하나씩 증가 시켜줘야 값이 달라지지 않는다.
아래 코드를 보자.
import java.util.*;
import java.io.*;
public class Main {
static int count;
static int[] myArr;
static int[] checkArr;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int S = Integer.parseInt(st.nextToken());
int P = Integer.parseInt(st.nextToken());
int result = 0;
char[] givenString = br.readLine().toCharArray();
myArr = new int[4];
checkArr = new int[4];
count = 0;
st = new StringTokenizer(br.readLine());
for(int i = 0; i < 4; i++) {
checkArr[i] = Integer.parseInt(st.nextToken());
if(checkArr[i] == 0) count++;
}
for(int i = 0; i < P; i++) {
Add(givenString[i]);
}
if(count == 4) {
result++;
}
for(int i = P; i < S; i++) {
int j = i - P;
Add(givenString[i]);
Remove(givenString[j]);
if(count == 4) {
result++;
}
}
System.out.println(result);
}
private static void Remove(char c) {
switch (c) {
case 'A':
if(myArr[0] == checkArr[0]) {
count--;
}
myArr[0]--;
break;
case 'C':
if(myArr[1] == checkArr[1]) {
count--;
}
myArr[1]--;
break;
case 'G':
if(myArr[2] == checkArr[2]) {
count--;
}
myArr[2]--;
break;
case 'T':
if(myArr[3] == checkArr[3]) {
count--;
}
myArr[3]--;
break;
}
}
private static void Add(char c) {
switch (c) {
case 'A':
myArr[0]++;
if(myArr[0] == checkArr[0]) {
count++;
}
break;
case 'C':
myArr[1]++;
if(myArr[1] == checkArr[1]) {
count++;
}
break;
case 'G':
myArr[2]++;
if(myArr[2] == checkArr[2]) {
count++;
}
break;
case 'T':
myArr[3]++;
if(myArr[3] == checkArr[3]) {
count++;
}
break;
}
}
}