您的位置:首页 > 编程语言 > PHP开发

FTPrep, 97 Interleaving String

2017-10-06 08:08 260 查看
这是一道典型的 动态规划的题目,而且是2D DP, 照理说是要用一个2D array来记录判断情况的。

最初的原型是Edit Distance。那里是判断最少的 edit 次数 使得两个string 相同。

这里的话有所变化,但其实本质上还是一样的,就是看path是往 右边走 还是 下边走,往右是因为shortWord的下一个字母和string3中的字母match,往下边走是因为string3中的字母和longWord的字母match。搞清楚了这两种延续的情况,代码中的变换方程也就不难写了。

代码如下:

class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
int len1=s1.length();
int len2=s2.length();
if(len1+len2!=s3.length()) return false; // easy to check!
String shortString=len1<len2?s1:s2;
String longString=len1<len2?s2:s1;

boolean[] record = new boolean[shortString.length()+1];
record[0]=true;
for(int i=0; i<record.length-1; i++){
record[i+1]=record[i]&&(shortString.charAt(i)==s3.charAt(i));
}

for(int j=0; j<longString.length(); j++){
record[0]=record[0]&&(longString.charAt(j)==s3.charAt(j));
for(int i=0; i<record.length-1; i++){  // exactly the same as line 10
record[i+1]= (record[i+1]&&(longString.charAt(j)==s3.charAt(i+j+1)))||(record[i]&&(shortString.charAt(i)==s3.charAt(i+j+1)));
}
}
return record[record.length-1];
}
}


TODO: edit distance 的代码放在下面可供对比:不同的地方:1,这里记录的是edit的次数;2,需要多一个newRecord的数组,因为上一排的信息是必须的,即左上角位置的数字信息不能丢失。

class Solution {
public int minDistance(String word1, String word2) {
int len1 = word1.length();
int len2 = word2.length();
if(len1==0) return len2;
if(len2==0) return len1;
String shortWord = len1<len2?word1:word2;
String longWord = len1<len2?word2:word1;
int[] record = new int[shortWord.length()+1];
for(int i=0; i<shortWord.length()+1; i++) record[i]=i;
for(int j=0; j<longWord.length(); j++){
int[] newRecord = new int[shortWord.length()+1];
newRecord[0] = j+1; // the first elem present that the (j+1)th char in the longWord
for(int i=0; i<shortWord.length(); i++){
// newRecord[i] keep the distance between shortWord[i-1] and longWord[j], this is the difference!!
// following the above comment, to get record[i+1], we need to compare shortWord[i] and longWord[j];
if(shortWord.charAt(i)==longWord.charAt(j)) newRecord[i+1]=record[i];
else{
newRecord[i+1]=Math.min(newRecord[i], Math.min(record[i], record[i+1]))+1;
}
}
record=newRecord;
}
return record[shortWord.length()];
}
}

自己又写了一遍,居然一次就通过了,哈哈,看来还是掌握的比较好。

代码和comment:

class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
int len1=s1.length();
int len2=s2.length();
if(len1+len2!=s3.length()) return false;
String shortStr=len1<len2?s1:s2;
String longStr=len1<len2?s2:s1;
int shortLen = shortStr.length();
int longLen = longStr.length();

boolean[] record = new boolean[1+shortLen];
record[0]=true;
for(int i=0; i<shortLen; i++){  // i is the index in the shortStr, the result is in record[i+1] though
record[i+1] = record[i]&&(shortStr.charAt(i)==s3.charAt(i));
}

for(int j=0; j<longLen; j++){  // j is also the index in the longStr.
record[0] = record[0] && (longStr.charAt(j)==s3.charAt(j));
for(int i=0; i<shortLen; i++){
record[i+1] = (record[i+1]&&(longStr.charAt(j)==s3.charAt(i+j+1))) || (record[i] && (shortStr.charAt(i)==s3.charAt(i+j+1)));
} // when i and j are index in shortStr and longStr, it is i+j+1 in the s3, since it is the length directly matches, not index
}

return record[shortLen];
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: