The LCS problem is a classic problem of dynamic programming, and it is also considered an entry problem. The goal is to require the longest common substring of two strings. For example the following two strings:
string 1:abcbdab
string 2:bdcaba
So, their longest common subsequence is BCBA. Note that the longest common subsequence is not the longest public string, the longest public string in Leetcode seems to have such a problem, with the method of brute force can be calculated in a very short period of time, will not take too long. But the longest common subsequence is not sequential, and to find out, you need to enumerate all the possibilities in the string, which requires exponential time complexity. Pure brute force algorithm can be difficult to calculate in a very short period of time. So we have a dynamic programming of the LCS algorithm.
look at the book's Theorem on the optimal substructure of LCS:
make x = <x1,... xm> y=<y1,.... yn> to two sequences and Z to any LCS in X,y:
1. If Xm = Yn, then ZK!= xm, and Zk-1 is an LCS of Xm-1
2. If XM!= Yn, then ZK! = Yn, and Zk-1 as an LCS for Yn-1
So how do we construct the identity LCS in our code?
First we define two two-dimensional matrices, B and C, and the dimension is two strings of length +1. The corresponding matrix is then generated according to the following rules loop or the cabinet.
1. If i=0 or j=0:c[i][j]=0, b[i][j]= '.
2. If I,j>0 and x[i]=y[j] c[i][j] = c[i-1][j-1], b[i][j] = ' x ' represents up ARROW
3. If i,j>0 and x[i]!=y[j] c[i][j] = max (C[i-1][j], c[i-1][j-1]) b[i][j] = ' h ' or ' W ' stands for vertical and horizontal arrows
The resulting matrix is shown in the following illustration: where x refers to a diagonal arrow, h refers to a vertical arrow, and w points to a horizontal arrow:
Then, according to the recursive way, from the last column in turn to look forward, if it is a diagonal arrow, record the two-way value at this time, the vertical arrow is moved up, the horizontal arrow moves to the left. Finally, the following results are obtained:
Each turning point is the common substring to be obtained.
Here is the code for the Java implementation:
Private stack<character> Stack = new stack<character> (); private void Printlcs (char d[][], String A, int i, int j) {if i==0| |
j==0) {} else if (d[i][j]== ' x ') {Stack.push (A.charat (i-1));
Printlcs (d,a,i-1,j-1);
else if (d[i][j]== ' h ') Printlcs (D,A,I-1,J);
else Printlcs (d,a,i,j-1);
public string Getlcs (string a,string b) {int[][] c = new Int[a.length () +1][b.length () +1];
Char[][] D = new char [A.length () +1][b.length () +1];
for (int i = 0; I<=a.length (); i++) c[i][0]=0;
for (int j = 0; J<=b.length (); j + +) d[0][j]=0;
for (int i = 1; i<=a.length (); i++) {for (int j = 1; J<=b.length (); j +) {if (A.charat (i-1) ==b.charat (j-1))
{C[i][j] = c[i-1][j-1]+1; D[i][j] = ' x '; else if (C[i-1][j] >= c[i][j-1]) {c[i][j] = c[i-1][j];
D[I][J] = ' h '; else {C[i][j] = c[i][j-1];
D[I][J] = ' W ';
}} Printlcs (d, A, a.length (), b.length ());
String res = ""; while (!sTack.empty ()) res = Stack.pop (). toString ();
return res; }