From 0e73afc194ef48d6e87a577b38045fb4039a770c Mon Sep 17 00:00:00 2001 From: JIA Date: Sat, 3 Jan 2026 17:14:37 +0900 Subject: [PATCH] =?UTF-8?q?-=208=EC=A3=BC=EC=B0=A8=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=ED=92=80=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- longest-common-subsequence/Geegong.java | 99 +++++++++++++++++++------ 1 file changed, 77 insertions(+), 22 deletions(-) diff --git a/longest-common-subsequence/Geegong.java b/longest-common-subsequence/Geegong.java index 2ff0a6575d..a3008986b1 100644 --- a/longest-common-subsequence/Geegong.java +++ b/longest-common-subsequence/Geegong.java @@ -20,36 +20,91 @@ public class Geegong { * @return */ public int longestCommonSubsequence(String text1, String text2) { - char[] chText1 = text1.toCharArray(); - char[] chText2 = text2.toCharArray(); - - // text1만 각 원소 별로 char가 가지는 index를 array 로 갖는 배열을 생성 - List[] positionIndices = new List[26]; - for (int index = 0; index O (N) + * space complexity : O(M * N) => O (N) + */ + char[] ch1 = text1.toCharArray(); + char[] ch2 = text2.toCharArray(); + + int[][] LISArr = new int[ch1.length + 1][ch2.length + 1]; + + // first, fill zeros in first row, first column for convenient + for (int idx=0; idx<=ch2.length; idx++) { + LISArr[0][idx] = 0; } + for (int idx=0; idx<=ch1.length; idx++) { + LISArr[idx][0] = 0; + } - // 여기서부터 LIS 를 구할것임 - List indices = new ArrayList<>(); - for (int index=0; index 0) { - // 역순 (LIS 를 구하기 위해서 일부러 뒤집어 높음, 즉 각 char 별 LIS 를 구할것이기 때문에..) - // positionIndices 에서 구했던 값들을 그대로 addAll 한다면 오름차순이 되기때문에 정확한 LIS 를 구할 수 없다 + // if same, then + if (ch1[index1] == ch2[index2]) { + // LISArr 의 인덱스값이 +1 이 되는 이유는 LISArr 의 크기가 text1, text2 크기 + 1 만큼 만들었기 때문 + LISArr[index1 + 1][index2 + 1] = LISArr[index1][index2] + 1; + } else { + int biggerOne = Math.max(LISArr[index1][index2 + 1], LISArr[index1 + 1][index2]); + LISArr[index1 + 1][index2 + 1] = biggerOne; + } - indices.addAll(positionIndices[find-'a'].stream().sorted(Comparator.reverseOrder()).toList()); + maxLIS = Math.max(maxLIS, LISArr[index1 + 1][index2 + 1]); } } - // find LIS - return findLIS(indices).size(); + return maxLIS; + + + + /** + * LIS, LCS 와 연관지어서 풀이 + * 1. 먼저 text1을 훑어보는데 text1에 중복되는 알파벳이 있을 수 있기에 각 캐릭터별로 인덱스들을 저장 (각 원소가 arrayList가 있는 배열) + * 2. text2 를 훑으면서 매칭되는 캐릭터들에 대해서만 1에서 저장된 인덱스들을 한 배열안에 나열 + * -> 이떄 나열해서 넣을때마다 역순으로 집어넣는게 중요! (왜냐면 이 나열된 인덱스들을 가지고 LIS를 구할거라서) + * 3. 나열된 인덱스들의 값들을 가지고 LIS 를 구한다, 즉 이 LIS의 길이가 LCS 의 길이가 된다..!! (와우 신기) + * 그러나 leet code 에 돌렸을 때 runtime 이 영 좋지는 않음 + * + * time complexity : O(M + N logN) => text2에 대해서 문자마다 바이너리서치가 수행됨 + * space complexity : O(M+N) + */ +// char[] chText1 = text1.toCharArray(); +// char[] chText2 = text2.toCharArray(); +// +// // text1만 각 원소 별로 char가 가지는 index를 array 로 갖는 배열을 생성 +// List[] positionIndices = new List[26]; +// for (int index = 0; index indices = new ArrayList<>(); +// for (int index=0; index 0) { +// // 역순 (LIS 를 구하기 위해서 일부러 뒤집어 높음, 즉 각 char 별 LIS 를 구할것이기 때문에..) +// // positionIndices 에서 구했던 값들을 그대로 addAll 한다면 오름차순이 되기때문에 정확한 LIS 를 구할 수 없다 +// +// indices.addAll(positionIndices[find-'a'].stream().sorted(Comparator.reverseOrder()).toList()); +// } +// } +// +// // find LIS +// return findLIS(indices).size(); } public List findLIS(List source) {