티스토리 뷰

알고리즘/백준

[BOJ] 백준 9251 LCS (JAVA)

오딩이 2022. 3. 24. 01:04

출처 : https://www.acmicpc.net/problem/9251 

 

9251번: LCS

LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다. 예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다.

www.acmicpc.net

 

🔍 Solve

완전 탐색으로 문자열 1과 문자열 2를 비교하는 방법을 생각했었는데, 카테고리가 dp인 만큼 시간 초과가 났습니다. 

dp배열에서 i=0, j=0일 때 i-1, j-1을 비교해야하기 때문에 dp배열의 크기는 (문자열 1의 길이+1) * (문자열 2의 길이+1)로 설정하였습니다.

문자열의 문자들을 비교하면서 문자가 같지 않을 땐 dp[i-1][j]와 dp[i][j-1] 중 큰 수를 저장하고, 문자가 같을 땐 dp[i-1][j-1]+1을 저장하였습니다.

그림의 노란색으로 표시된 곳을 해석해보면, {A, C, A} 집합과 {C, A}집합의 LCS가 2라는 것을 의미합니다.

문제를 풀면서 문자열이 같을 때 dp[i-1][j]와 dp[i][j-1] 중 큰 수에 1을 더한 값을 저장하는 실수를 했습니다.

해당 로직은 두 문자열이 ABAAB, AA일 때 반례를 찾을 수 있었습니다.

 

Code

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    static char[] chars1;  //문자열1 char집합
    static char[] chars2;  //문자열2 char집합
    static int[][] dp; 
    static int maxLength = Integer.MIN_VALUE; //LCS의 최댓값

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String str1 = br.readLine();
        String str2 = br.readLine();

        chars1 = str1.toCharArray();
        chars2 = str2.toCharArray();

        //dp배열에서 i=0, j=0일 때 i-1, j-1을 탐색하기위해 +1의 크기만큼 배열 선언
        dp = new int[chars1.length+1][chars2.length+1];

        for(int i=1;i<=chars1.length;i++){
            for(int j=1;j<=chars2.length;j++){

                int temp = Math.max(dp[i-1][j], dp[i][j-1]);  //temp = dp배열의 위, 왼쪽 값 중 큰 값 저장
                if(chars1[i-1]==chars2[j-1]){ //만약 두 char가 같으면
                    /*
//                    temp += 1;
                        일 때 안되는 반례
                        str1 = ABAABA
                        str2 = AA
                        temp = Math.max(dp[i-1][j], dp[i][j-1])+1 일 땐 -> 답이 5
                        temp = dp[i-1][j-1]+1일 땐 -> 답이 2
                    */
                    temp = dp[i-1][j-1]+1;  //temp는 dp배열 대각선 위의 값에 +1
                }
                dp[i][j] = temp;  //dp배열에 temp값 저장
                maxLength = Math.max(maxLength, dp[i][j]);  //dp배열 갱신할 때마다 가장 큰 값 저장
            }
        }

        System.out.println(maxLength);

    }
}

'알고리즘 > 백준' 카테고리의 다른 글

[BOJ] 백준 9465 스티커 (JAVA)  (0) 2022.03.24
[BOJ] 백준 17070 파이프옮기기1 (JAVA)  (0) 2022.03.17
[BOJ] 백준 1976 여행가자 (JAVA)  (0) 2022.03.17
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함