思路:後綴是指要解決的子問題是原問題的後半部分,若是用字符串類描述,至關於子問題永遠都是原問題的後半部分 str[i:]數組
str[i:] 表示從下標i開始,一直到末尾的整個字符串bash
給定兩個字符串A:HIEROGLYPHOLOGY
和字符串B:MICHAELANGELO
,他們最長公共的子序列爲ui
HIEROGLYPHOLOGY <--> MICHAELANGELOspa
能夠獲得最長公共子序列長度爲5。分析以下:3d
最終要計算的結果是 dp(A.length()-1,B.length()-1)。即字符串A和字符串B的最長公共子序列長度。
假設輸入的字符串A是 HIE
B是 MCHI
,目標就是要計算dp(2,3)code
2表示A字符串的最後一個下標,3表示B字符串的最後一個下標cdn
橫座標表示字符串A中參與計算最長公共子序列長度的最後一個字符;縱座標表示字符串B中參與計算最長公共子序列長度的最後一個字符blog
x 表示剩餘須要比較的子字符開始的位置ip
- 表示當前圖表中沒有寫這個分支,只看挑選的分支執行路徑
從上面的分析過程能夠看到,要計算對應的位置的值,必須先把它以前的值都準備好,才能繼續進行,也就是說,若是以前已經計算過,就能夠利用它繼續計算,不然只能回過頭來再計算一遍,這樣也不划算,既然如此,就能夠按照從橫座標0開始,一行一行的填充數據。字符串
當A取下標0的時候,就是隻有1個字母和整個B字符串去對比,當A取下標1的時候,就是A[0:1]去和B對比,對應的操做順序以下
顯示按照藍線,而後是綠線最後是黃線,而後計算出值。public int longestCommonSubsequence(String A, String B) {
// 特殊狀況直接返回
if(A==null || "".equals(A) || B==null || "".equals(B)){
return 0;
}
int length=0;
int [][] arr=new int[A.length()+1][B.length()+1];
//從1開始是由於只要當前有一個是同樣的,後面的至少和他保持一致,最長序列不會比它少,若是從0開始,那麼須要有額外的邏輯去保證第0行的正確性,而從1開始就能夠很好的利用現有的邏輯,沒必要寫過多的冗餘代碼
for(int i=1;i<=A.length();i++){
for(int j=1;j<=B.length();j++){
if(A.charAt(i-1)==B.charAt(j-1)){
arr[i][j]=arr[i-1][j-1]+1;
}else{
arr[i][j]=Math.max(arr[i-1][j],arr[i][j-1]);
}
}
}
return arr[A.length()][B.length()];
}
複製代碼
給兩個字符串 word1 和 word2,找到最少的步驟,使得word1可以變成word2,可使用的操做包括
好比 "mart" 變成 "karma" 最少須要3步。分析以下
從上面的最長公共字串思想,能夠類比,要使一個字串變成另一個字串,根據提供的3中操做方式,分別要去這三種可能性的最小值。假定給的字符串是A和B,A要變成B,首先從第一個字符開始
一樣用dp表示從第0個下標開始,須要計算的最小值上面三種狀況的最小值,數組自己是從0開始的,那從-1開始就表明一個字符都沒有,顯然這樣的編輯距離就是另一個有的長度,這也就使得初始值被創建,最終獲得的程序以下
public int minDistance(String word1, String word2) {
// write your code here
if(null == word1 || null == word2){
return 0;
}
int[][] arr=new int[word1.length()+1][word2.length()+1];
for(int i=0;i<=word1.length();i++){
arr[i][0]=i;
}
for(int j=1;j<=word2.length();j++){
arr[0][j]=j;
}
for(int i=1;i<=word1.length();i++){
for(int j=1;j<=word2.length();j++){
if(word1.charAt(i-1)==word2.charAt(j-1)){
arr[i][j]=Math.min(Math.min(arr[i][j-1]+1,arr[i-1][j]+1),arr[i-1][j-1]);
}else{
arr[i][j]=Math.min(Math.min(arr[i][j-1]+1,arr[i-1][j]+1),arr[i-1][j-1]+1);
}
}
}
return arr[word1.length()][word2.length()];
}
複製代碼