1
+ package DynamicProgramming .LongestCommonSubsequence ;
2
+
3
+ import java .util .ArrayList ;
4
+ import java .util .List ;
5
+
6
+ // import java.util.Arrays;
7
+
8
+ /**
9
+ * * Longest Common Subsequence (LCS) Problem
10
+ */
11
+
12
+ public class Solution {
13
+ public int longestCommonSubsequence (String s1 , String s2 ) {
14
+ // return longestCommonSubsequenceRec(
15
+ // s1.length(), s2.length(),
16
+ // s1.toCharArray(), s2.toCharArray()
17
+ // );
18
+
19
+ // int[][] cache = new int[s1.length() + 1][s2.length() + 1];
20
+ // for (int[] row : cache) Arrays.fill(row, -1);
21
+
22
+ // return longestCommonSubsequenceMem(s1.length(), s2.length(), s1.toCharArray(), s2.toCharArray(), cache);
23
+
24
+ return longestCommonSubsequenceDP (s1 , s2 );
25
+
26
+ // return longestCommonSubsequenceDPSpaceOpt(s1, s2);
27
+ }
28
+
29
+ /**
30
+ * * Dynamic Programming Approach (Space Optimized)
31
+ *
32
+ * * TC: O(mn)
33
+ * * SC: O(n)
34
+ */
35
+ // private int longestCommonSubsequenceDPSpaceOpt(String s1, String s2) {
36
+ // int m = s1.length(), n = s2.length(), idx = 0;
37
+ // int[][] dp = new int[2][n + 1];
38
+
39
+ // for (int i = 1; i < m + 1; i++) {
40
+ // // Calculate whether the the
41
+ // // current row is even/odd.
42
+ // idx = i & 1;
43
+ // for (int j = 1; j < n + 1; j++) {
44
+ // if (s1.charAt(i - 1) == s2.charAt(j - 1))
45
+ // dp[idx][j] = 1 + dp[1 - idx][j - 1];
46
+ // else
47
+ // dp[idx][j] = Math.max(
48
+ // dp[1 - idx][j],
49
+ // dp[idx][j - 1]
50
+ // );
51
+ // }
52
+ // }
53
+
54
+ // return dp[idx][n];
55
+ // }
56
+
57
+ /**
58
+ * * Dynamic Programming Approach
59
+ *
60
+ * * TC: O(mn)
61
+ * * SC: O(mn)
62
+ */
63
+ private int longestCommonSubsequenceDP (String s1 , String s2 ) {
64
+ int m = s1 .length (), n = s2 .length ();
65
+ int [][] dp = new int [m + 1 ][n + 1 ];
66
+
67
+ for (int i = 1 ; i < m + 1 ; i ++) {
68
+ for (int j = 1 ; j < n + 1 ; j ++) {
69
+ if (s1 .charAt (i - 1 ) == s2 .charAt (j - 1 ))
70
+ dp [i ][j ] = 1 + dp [i - 1 ][j - 1 ];
71
+ else
72
+ dp [i ][j ] = Math .max (
73
+ dp [i - 1 ][j ],
74
+ dp [i ][j - 1 ]
75
+ );
76
+ }
77
+ }
78
+
79
+ System .out .println (buildSequence (s1 , s2 , dp ));
80
+
81
+ return dp [m ][n ];
82
+ }
83
+
84
+ private String buildSequence (String s1 , String s2 , int [][] dp ) {
85
+ List <String > seq = new ArrayList <>();
86
+
87
+ int i = s1 .length (), j = s2 .length ();
88
+
89
+ while (i > 0 && j > 0 ) {
90
+ if (s1 .charAt (i - 1 ) == s2 .charAt (j - 1 )) {
91
+ seq .add (0 , String .valueOf (s1 .charAt (i - 1 )));
92
+ --i ;
93
+ --j ;
94
+ }
95
+ else if (dp [i - 1 ][j ] > dp [i ][j - 1 ]) --i ;
96
+ else --j ;
97
+ }
98
+
99
+ return String .join ("" , seq );
100
+ }
101
+
102
+ /**
103
+ * * Memoization Approach
104
+ *
105
+ * * TC: O(mn)
106
+ * * SC: O(mn)
107
+ */
108
+ // private int longestCommonSubsequenceMem(int m, int n, char[] c1, char[] c2, int[][] cache) {
109
+ // if (m == 0 || n == 0) return 0;
110
+
111
+ // if (cache[m][n] != -1) return cache[m][n];
112
+
113
+ // if (c1[m - 1] == c2[n - 1])
114
+ // return cache[m][n] = 1 + longestCommonSubsequenceMem(m - 1, n - 1, c1, c2, cache);
115
+
116
+ // return cache[m][n] = Math.max(
117
+ // longestCommonSubsequenceMem(m - 1, n, c1, c2, cache),
118
+ // longestCommonSubsequenceMem(m, n - 1, c1, c2, cache)
119
+ // );
120
+ // }
121
+
122
+ /**
123
+ * * Recursive Approach
124
+ *
125
+ * * TC: O(3^(m + n)) approximately
126
+ * * SC: O(3^(m + n)) approximately
127
+ */
128
+ // private int longestCommonSubsequenceRec(int m, int n, char[] c1, char[] c2) {
129
+ // if (m == 0 || n == 0) return 0;
130
+
131
+ // if (c1[m - 1] == c2[n - 1])
132
+ // return 1 + longestCommonSubsequenceRec(m - 1, n - 1, c1, c2);
133
+
134
+ // return Math.max(
135
+ // longestCommonSubsequenceRec(m - 1, n, c1, c2),
136
+ // longestCommonSubsequenceRec(m, n - 1, c1, c2)
137
+ // );
138
+ // }
139
+
140
+ public static void main (String [] args ) {
141
+ Solution solution = new Solution ();
142
+
143
+ // should be 3
144
+ System .out .println (solution .longestCommonSubsequence ("ABCDGH" , "AEDFHR" ));
145
+
146
+ // should be 4
147
+ System .out .println (solution .longestCommonSubsequence ("AGGTAB" , "GXTXAYB" ));
148
+ }
149
+ }
0 commit comments