最长公共子序列
/*
1. 最长公共子序列(LCS)问题
通过构建表格(二维数组),来求两个结构的公共部分有奇效。
2. 最长递增子序列LIS的问题
设原数组为A
把原数组递增排序为A'
求A和A’的最长公共子序列即可。
动态规划,综合上几步计算出的信息,算出下一步的值。
因此需要维护一存储空间。
参考链接:
http://blog.csdn.net/github_36487770/article/details/66532403
http://blog.csdn.net/lisonglisonglisong/article/details/41596309
*/
function lstd(stra, strb) {
var n, i, j;
var dp = [], lst = [];
var arr = stra.split("");
var brr = strb.split("");
var lena = arr.length;
var lenb = brr.length;
var LCSArr = [];
// 构建二维数组,也就是表格
for (i = 0; i < lena + 1; i++) {
dp[i] = [];
for (j = 0; j < lenb + 1; j++) {
if (i == 0 || j == 0) dp[i][j] = 0;
else if (arr[i] === brr[j]) { dp[i][j] = dp[i - 1][j - 1] + 1; }
else { dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); }
}
}
var lst = "";
// 回溯,获取公共子序列
var traceback = function (i, j, lst) {
while (i > 0 && j > 0) {
if (arr[i - 1] === brr[j - 1]) {
lst += arr[i - 1];
if (lst.length === dp[lena][lenb]) {
LCSArr.push(lst.split("").reverse().join(""));
}
i--; j--;
}
else {
if (dp[i - 1][j] > dp[i][j - 1]) { --i; }
else if (dp[i - 1][j] < dp[i][j - 1]) { --j; }
else {
traceback(i - 1, j, lst);
traceback(i, j - 1, lst);
return; //千万不要忘了return!!!
}
}
}
};
traceback(lena, lenb, lst);
return {
length:dp[lena][lenb], //公共子序列的最大长度
LCS: LCSArr
}
}
let x = "ABCBDAB";
let y = "BDCABA";
console.log(lstd(x, y).LCS);
合乎自然而生生不息。。。