一道常見的前端面試題前端
原理是動態規劃面試
找了一篇博客來說解這個部分,不過用Java實現的數組
原址在: https://my.oschina.net/leejun2005/blog/117167bash
/////////////////////複製他人博客部分/////////////////////////ui
利用矩陣來保存子串數量信息spa
一、先科普下最長公共子序列 & 最長公共子串的區別:.net
找兩個字符串的最長公共子串,這個子串要求在原字符串中是連續的。而最長公共子序列則並不要求連續。code
二、最長公共子串blog
其實這是一個序貫決策問題,能夠用動態規劃來求解。咱們採用一個二維矩陣來記錄中間的結果。這個二維矩陣怎麼構造呢?直接舉個例子吧:"bab"和"caba"(固然咱們如今一眼就能夠看出來最長公共子串是"ba"或"ab")字符串
b a b
c 0 0 0
a 0 1 0
b 1 0 1
a 0 1 0
咱們看矩陣的斜對角線最長的那個就能找出最長公共子串
不過在二維矩陣上找最長的由1組成的斜對角線也是件麻煩費時的事,下面改進:當要在矩陣是填1時讓它等於其左上角元素加1。
b a b
c 0 0 0
a 0 1 0
b 1 0 2
a 0 2 0
這樣矩陣中的最大元素就是 最長公共子串的長度。
在構造這個二維矩陣的過程當中因爲得出矩陣的某一行後其上一行就沒用了,因此實際上在程序中能夠用一維數組來代替這個矩陣。
////////////////////////////////////////////////////////////
function csm (str1, str2) {
let l1 = str1.length;
let l2 = str2.length;
let strArr1 = str1.split('');
let strArr2 = str2.split('');
let ma = [];
let max = 0;
for (let i = 0; i < l1; i++) {
let sa = [];
for (let j = 0; j < l2; j++) {
sa[j] = 0;
}
ma.push(sa);
}
for (let m = 0; m < l1; m++) {
for (let n = 0; n < l2; n++) {
if (strArr1[m] === strArr2[n]) {
//處理邊界
if (m == 0 || n == 0) {
ma[m][n] = 1;
} else {
ma[m][n] = ma[m - 1][n - 1] + 1;
}
max = Math.max(max, ma[m][n]);
}
}
}
return max;
}
複製代碼