1-定義:
一個字符串的 子序列 是指這樣一個新的字符串:它是由原字符串在不改變字符的相對順序的情況下刪除某些字符(也可以不刪除任何字符)後組成的新字符串。
* 例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。
* 兩個字符串的「公共子序列」是這兩個字符串所共同擁有的子序列。
* 若這兩個字符串沒有公共子序列,則返回 0。
2-應用
在前端組件框架裏面,很常見的dom處理就是將一個dom樹切換爲另外一個dom樹,現代的mvvm框架基本都是在dom樹的每一層上去做diff的。簡化的來看就是要以最小的開銷從 "abcde" 切換到 "ace"。
3-動態規劃的思想
最優子結構就是說: "abcde" 和 "ace" 的最長公共子序列,因爲倆個字符串最後的e都相同,那麼他們的公共子序列肯定是 “abcd” 和 “ac” 的公共子序列數值上加1;“abcd” 和 “ac”的公共子序列,因爲最末尾 d 和 c 不一致,所以結果會是 “abc” 和 “ac” 公共子序列以及 “abcd” 和 “a” 的公共子序列中較多的那一個 。
4-代碼實現:
longestCommonSubsequence = (str1,str2
) => {
let lg1=str1.length;
let lg2=str2.length;
let dp=[(new Array(lg2+1)).fill(0)];//初始化棋盤第一行,全爲0;
for(let i=0;i<lg1;i++){//一行一行遍歷
dp[i+1]=[0];//初始化每一行的第一列,全爲0;
for(let j=0;j<lg2;j++){
if(str1[i] == str2[j]){
dp[i+1][j+1] =dp[i][j]+1;
}
else{
dp[i+1][j+1] = Math.max(dp[i][j+1], dp[i+1][j]);
}
}
}
console.log(dp);
return dp[dp.length-1][dp[0].length-1];
};
結果如下圖: