思路:后缀是指要解决的子问题是原问题的后半部分,若是用字符串类描述,至关于子问题永远都是原问题的后半部分 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()];
}
复制代码