leetcode interleaving String
这道题如下:
Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.
For example,
Given:
s1 = "aabcc"
,
s2 = "dbbca"
,
When s3 = "aadbbcbcac"
, return true.
When s3 = "aadbbbaccc"
, return false.
一开始觉得这道题很简单,设置三个指针,往前挪就行了,提交后有个test无法通过,
即,s1="aa",s2="ab",s3="aaba",在这个例子中,问题在于,s3[1]的'a'有两个匹配选择,
选择哪一个?
自然想到使用backtracing,然而超时。此时想到了之前的那道edit distance 的题目,这道题
和它类似,我们可以用dynamic programming 的方法求解。
基本思路为,设置一个二维数组dp[m+1][n+1],m是s1的长度,n是s2的长度。
那么对于dp[i][j]来说,如果dp[i-1][j]为true 的话,那么说明
sub1,sub2,sub3满足题设,即时interleaving string,其中,sub1是s1.substring(0,i),sub2是s2.substring(0,j+1),sub3是s3.substring(0,i+j)
那么此时,如果s1.charAt(i)==s3.charAt(i+j)成立,那么说明dp[i][j]也为true
同理,从dp[i][j-1]是另一条推断dp[i][j]的路径,这两条路径只要有一条为true,那么dp[i][j]为true。
如此迭代,即可求出dp[i][j]的值,它即是我们所求的答案。
下面给出代码
public class Solution2 { /** * @param args */ public boolean isInterleave(String s1, String s2, String s3) { boolean dp[][]=new boolean[s1.length()+1][s2.length()+1]; for(int i=1;i<=s1.length();i++) { if(s1.charAt(i-1)==s3.charAt(i-1)) dp[i][0]=true; else { for(;i<s1.length();i++) dp[i][0]=false; break; } } for(int i=1;i<=s2.length();i++) { if(s2.charAt(i-1)==s3.charAt(i-1)) dp[0][i]=true; else { for(;i<s2.length();i++) dp[0][i]=false; break; } } for(int i=1;i<=s1.length();i++) for(int j=1;j<=s2.length();j++) { if(!dp[i-1][j]&&!dp[i][j-1]) { dp[i][j]=false;continue;} if(dp[i-1][j]&&s1.charAt(i-1)==s3.charAt(i+j-1)) dp[i][j]=true; else if(dp[i][j-1]&&s2.charAt(j-1)==s3.charAt(i+j-1)) dp[i][j]=true; } Print(dp); return dp[s1.length()][s2.length()]; } public static void Print(boolean dp[][]) { for(boolean[] d:dp) {String result=""; for(boolean b:d) { result+=b+","; } System.out.println(result); } } public static void main(String[] args) { // TODO Auto-generated method stub String s1="a"; String s2="b"; String s3="a"; System.out.println(new Solution2().isInterleave(s1, s2, s3)); } }