-
Notifications
You must be signed in to change notification settings - Fork 458
/
Copy pathLCS1.java
84 lines (65 loc) · 2.13 KB
/
LCS1.java
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import java.util.Arrays;
/// LCS问题
/// 动态规划
/// 时间复杂度: O(len(s1)*len(s2))
/// 空间复杂度: O(len(s1)*len(s2))
public class LCS1 {
private int[][] memo;
public String lcs(String s1, String s2){
if(s1 == null || s2 == null)
throw new IllegalArgumentException("s1 and s2 can not be null.");
if(s1.length() == 0 || s2.length() == 0)
return "";
memo = new int[s1.length()][s2.length()];
for(int i = 0 ; i < s1.length() ; i ++)
Arrays.fill(memo[i], -1);
lcs(s1, s2, s1.length() - 1, s2.length() - 1);
return getLCS(s1, s2);
}
// 求s1[0...m]和s2[0...n]的最长公共子序列的长度值
private int lcs(String s1, String s2, int m, int n){
if(m < 0 || n < 0)
return 0;
if(memo[m][n] != -1)
return memo[m][n];
int res = 0;
if(s1.charAt(m) == s2.charAt(n))
res = 1 + lcs(s1, s2, m - 1, n - 1);
else
res = Math.max(lcs(s1, s2, m - 1, n),
lcs(s1, s2, m, n - 1));
memo[m][n] = res;
return res;
}
// 通过memo反向求解s1和s2的最长公共子序列
private String getLCS(String s1, String s2){
int m = s1.length() - 1;
int n = s2.length() - 1;
StringBuilder res = new StringBuilder("");
while(m >= 0 && n >= 0)
if(s1.charAt(m) == s2.charAt(n)){
res = res.insert(0, s1.charAt(m));
m --;
n --;
}
else if(m == 0)
n --;
else if(n == 0)
m --;
else{
if(memo[m-1][n] > memo[m][n-1])
m --;
else
n --;
}
return res.toString();
}
public static void main(String[] args) {
String s1 = "ABCDGH";
String s2 = "AEDFHR";
System.out.println((new LCS1()).lcs(s1, s2));
s1 = "AAACCGTGAGTTATTCGTTCTAGAA";
s2 = "CACCCCTAAGGTACCTTTGGTTC";
System.out.println((new LCS1()).lcs(s1, s2));
}
}