Algorithm
[Algo] 백준 9252 LCS2 JAVA
조핑구
2024. 5. 8. 13:51
문제 바로가기 : https://www.acmicpc.net/problem/9252
메모리 : 19172KB
시간 : 172ms
언어 : Java 11
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Stack;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str1 = br.readLine();
String str2 = br.readLine();
int len1 = str1.length();
int len2 = str2.length();
int[][] arr = new int[len1 + 1][len2 + 1];
for (int i = 1; i <= len1; i++) {
for (int j = 1; j <= len2; j++) {
if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
arr[i][j] = arr[i - 1][j - 1] + 1;
} else {
arr[i][j] = Math.max(arr[i - 1][j], arr[i][j - 1]);
}
}
}
Stack<Character> stack = new Stack<>();
int i = len1;
int j = len2;
while (true) {
if (stack.size() == arr[len1][len2])
break;
if (arr[i][j] == arr[i][j - 1]) {
j--;
} else if (arr[i][j] == arr[i - 1][j]) {
i--;
}
if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
stack.add(str1.charAt(i - 1));
i--;
j--;
}
}
StringBuilder sb = new StringBuilder();
sb.append(arr[str1.length()][str2.length()]).append("\n");
while (!stack.isEmpty()) {
sb.append(stack.pop());
}
System.out.print(sb);
}
}
맨 처음에는 LCS알고리즘을 수행하며 String을 저장하는 이차원 배열을 같이 돌리는 코드를 생각했다. 당연히 이게 맞을 줄 알았는데.. 92%에서 시간초과가 나버린.... 어떤 방법을 써도 해결되지않았다ㅜ String+String 연산이 시간초과의 원인인 것 같다. String의 "+" 연산은 금기시 되어 있다는 사실을 알았다... >> 자세한 글 보기
검색을 통해 알아낸 해결방법.. LCS의 길이를 구하기 위한 DP배열을 거꾸로 올라가며 글자를 찾는 것이다. LCS알고리즘에서는 일치하는 부분에서 숫자를 늘려줬다(+1). 따라서 숫자가 늘어난 부분을 찾으면 그 글자가 일치하는 것이라고 볼 수 있다.
while (true) {
if (stack.size() == arr[len1][len2]) //모두 찾았으면 break
break;
//(i,j)에서 왼쪽과 위를 보며 같은 숫자를 찾아 떠난다.
//LCS에서 왼쪽과 위 중 큰 것을 저장하며 내려왔기 때문에. 내려온 대로 올라간다!
if (arr[i][j] == arr[i][j - 1]) {
j--;
} else if (arr[i][j] == arr[i - 1][j]) {
i--;
}
//일치하는 문자열을 찾으면 유레카
//그리고 대각선으로 올라간다. LCS에서 대각선+1 이었기 때문에.
if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
stack.add(str1.charAt(i - 1));
i--;
j--;
}
}