最长子序列(LCS)
当初备战蓝桥杯所学习的dp算法,加上了详细注释(程序小白欢迎指正)
由于注释比较详细这里不做过多赘述
Longest common subsequent
最长公共子序列(LCS)是一个在一个序列集合中(通常为两个序列)用来查找所有序列中最长子序列的问题。一个数列 ,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则称为已知序列的最长公共子序列。
提示:以下是本篇文章正文内容,下面案例可供参考
代码如下(示例):
package 算法训练;
import java.util.Arrays;
//最长子序列
public class LCS {
public static void main(String[] args) {
String[] s1 = {"A", "B", "C", "D", "A", "F"};
String[] s2 = {"A", "C", "B", "C", "F"};
lcs(s1, s2);
}
// dp解法
// 本算法是一个递推过程
// 所以首行首列的初始化initarr()是递推的基础
static int[][] arr;
private static void lcs(String[] s1, String[] s2) {
// 根据两个字串的长度生成二维表
arr = initarr(s1, s2);
// 遍历二维表
for (int i = 1; i < s2.length; i++) {
for (int j = 1; j < s1.length; j++) {
// 初始化第一行和第一列 我这里再遍历二维表的时候添加了一个首行首列判断,也可单独对首行首列进行初始化
// 判断是否s1和s2是否有匹配的元素?
if (s1[j].equals(s2[i])) {
// 如果匹配那就假设没有这个元素可以匹配多少?
int max = Math.max(arr[i - 1][j], arr[i][j - 1]);
// 然后加一就是当前位置的值
arr[i][j] = max + 1;
}
else {
// 否则就是不匹配
int max = Math.max(arr[i - 1][j], arr[i][j - 1]);
// 不匹配那就看没有当前行位置的这个元素和没有当前列上的元素取最大值就是当前位置的值
arr[i][j] = max;
}
}
}
// 将二维表二点值进行输出 末尾的值就是当前最长子序列的长度。
for (int i = 0; i < arr.length; i++) {
System.out.println(Arrays.toString(arr[i]));
}
System.out.println(arr[s1.length - 1][s2.length - 1]);
}
//初始化首行首列
private static int[][] initarr(String[] s1, String[] s2) {
arr= new int [s2.length][s1.length];
// 如果匹配一个 那么后面就都匹配
boolean flag = false;
for (int i = 0; i < s1.length; i++) {
if(s2[0].equals(s1[i])||flag==true){
flag = true;
// 将其后置为一
arr[0][i] = 1;
}
}
flag = false;
for (int i = 0; i < s2.length; i++) {
if(s1[0].equals(s2[i])||flag==true){
flag = true;
// 同理将其后置为一
arr[i][0] = 1;
}
}
return arr;
}
}