2023.06.17 / 새벽까지 풀었지만 시간초과.. 슬라이딩 윈도우 개념을 익히고 다시 풀어보자!
2023.06.18 / 해결완료
import java.io.*;
import java.util.*;
public class Main {
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());
String[] sArray = br.readLine().split("");
int[] nArray = new int[4];
int[] copyArray = Arrays.copyOf(nArray, 4);
st = new StringTokenizer(br.readLine());
for(int i = 0; i < 4; i++) {
nArray[i] = Integer.parseInt(st.nextToken());
}
int count = 0;
int startIndex = 0;
int endIndex = P-1;
int currentIndex = 0;
while(endIndex != S) {
if(currentIndex > endIndex) {
if(checkAllInclude(copyArray)) {
count++;
}
copyArray = Arrays.copyOf(nArray, 4);
startIndex++;
endIndex++;
currentIndex = startIndex;
}else if(sArray[currentIndex].equals("A")) {
copyArray[0]--;
currentIndex++;
}else if(sArray[currentIndex].equals("C")) {
copyArray[1]--;
currentIndex++;
}else if(sArray[currentIndex].equals("G")) {
copyArray[2]--;
currentIndex++;
}else if(sArray[currentIndex].equals("T")) {
copyArray[3]--;
currentIndex++;
}
}
System.out.println(count);
}
public static boolean checkAllInclude(int[] nArray) {
for(int i = 0; i < nArray.length; i++) {
if(nArray[i] != 0) {
return false;
}
}
return true;
}
}
endIndex가 S-1과 동일하지 않으면 반복문을 계속해서 수행하도록 조건을 설정한다.currentIndex가 endIndex의 값보다 클 경우 checkAllInclude메소드를 실행한다. 이 메소드는 매개변수로 받은 배열을 순차적으로 탐색하여 하나라도 0이 아닌경우는 false값을 리턴하고 그 외에는 true값을 리턴한다.count변수를 증가시키고 startIndex와 endIndex의 값을 증가시킨다.currentIndex의 값이 endIndex의 값보다 커졌으므로 다시 startIndex로 값을 초기화 시키고 배열 또한 다시 계산을 수행해야하기 때문에 copyArray의 값을 nArray값으로 세팅했다.startIndex와 endIndex의 값이 변경될때마다 새로 계산을 수행했기 때문에 시간초과가 발생한 것으로 판단하였다.위 문제를 해결하기 위해 슬라이딩 윈도우라는 개념을 찾아보았다. 슬라이딩 윈도우를 적용한 핵심 해결방법은 고정된 문자열외에 삭제되거나 추가되는 인덱스의 값만 계산하여 모든 알파벳이 들어가있는지 확인하면 되는 문제였다.
import java.io.*;
import java.util.*;
public class Main {
public static int result = 0;
public static int checkSecret = 0;
public static int[] nArray = new int[4];
public static int[] myArray = new int[4];
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());
String[] sArray = br.readLine().split("");
st = new StringTokenizer(br.readLine());
for(int i = 0; i < 4; i++) {
nArray[i] = Integer.parseInt(st.nextToken());
if(nArray[i] == 0) {
checkSecret++;
}
}
for(int i = 0; i < P; i++) {
add(sArray[i]);
}
if(checkSecret == 4) {
result++;
}
for(int i = P; i < S; i++) {
int j = i - P;
add(sArray[i]);
remove(sArray[j]);
if(checkSecret == 4) {
result++;
}
}
System.out.println(result);
}
public static void add(String curAlphabet) {
switch (curAlphabet) {
case "A":
myArray[0]++;
if (nArray[0] == myArray[0]) {
checkSecret++;
}
break;
case "C":
myArray[1]++;
if (nArray[1] == myArray[1]) {
checkSecret++;
}
break;
case "G":
myArray[2]++;
if (nArray[2] == myArray[2]) {
checkSecret++;
}
break;
case "T":
myArray[3]++;
if (nArray[3] == myArray[3]) {
checkSecret++;
}
break;
}
}
public static void remove(String curAlphabet) {
switch (curAlphabet) {
case "A":
if (nArray[0] == myArray[0]) {
checkSecret--;
}
myArray[0]--;
break;
case "C":
if (nArray[1] == myArray[1]) {
checkSecret--;
}
myArray[1]--;
break;
case "G":
if (nArray[2] == myArray[2]) {
checkSecret--;
}
myArray[2]--;
break;
case "T":
if (nArray[3] == myArray[3]) {
checkSecret--;
}
myArray[3]--;
break;
}
}
}
add(String curAlphabet)메서드를 호출한다. 이 메서드는 case문을 사용하여 A, C, G, T일때 myArray[i]의 값을 증가시키고 nArray[i]와 myArray[i]를 비교하여 같을 경우 checkSecret의 값을 증가시켰다. 반복문을 모두 수행 후 checkSecret의 값이 4일경우 result의 값을 증가시켰다.add(String curAlphabet)와 remove(String curAlphabet)메서드를 호출해주고 각 반복문마다 checkSecret의 값이 4일 경우 result를 증가시켜주었다.remove(String curAlphabet)의 경우 add(String curAlphabet)의 역순이라고 생각하면 코드를 작성할 수 있을 것이다.무작정 코드를 작성하는것이 중요한게 아니라, 시간복잡도를 고려해서 적절한 알고리즘을 선택하는것이 중요하다는 것을 알았다. 노력하자..
I like everything about it. It's a nice thing to share a great story https://iogames.games
let yourself be engrossed by the nail-biting action and spine-chilling sounds
https://amandahorroradventurer.com/