Interleaving String

Given s1s2s3, 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.

首先考虑的是用栈记录匹配的状态,代码如下,会超时

 1 public boolean isInterleave(String s1, String s2, String s3) {
 2         if(s1.length()+s2.length()!=s3.length()){
 3             return false;
 4         }
 5         Stack<Integer> stack1 = new Stack<Integer>();
 6         Stack<Integer> stack2 = new Stack<Integer>();
 7         stack1.push(-1);
 8         stack2.push(-1);
 9         while(!stack1.empty()){
10             int index1 = stack1.pop();
11             int index2 = stack2.pop();
12             if(index1+index2+2==s3.length()){
13                 return true;
14             }
15             if(index1+1<s1.length()&&s1.charAt(index1+1)==s3.charAt(index1+index2+2)){
16                 stack1.push(index1+1);
17                 stack2.push(index2);
18             }
19             if(index2+1<s2.length()&&s2.charAt(index2+1)==s3.charAt(index1+index2+2)){
20                 stack1.push(index1);
21                 stack2.push(index2+1);
22             }
23         }
24         return false;
25     }

然后想了想之前做过的题,考虑使用动态规划,设grid[i][j][k]表示s1.substring(0,i)和s2.substring(0,j)与s3.substring(0,k)是否是interleaving string,因此可得出状态方程

grid[i][j][k] = (s1.charAt(i-1) == s3.charAt(k-1) && grid[i-1][j][k-1]) || (s2.charAt(j-1) == s3.charAt(k-1) && grid[i][j-1][k-1])

代码如下:

 1 public boolean isInterleave(String s1, String s2, String s3) {
 2         boolean grid[][][] = new boolean[s1.length()+1][s2.length()+1][s3.length()+1];
 3         if(s1.length()+s2.length()!=s3.length()){
 4             return false;
 5         }
 6         if(s1.equals("")){
 7             return s2.equals(s3);
 8         }else if(s2.equals("")){
 9             return s1.equals(s3);
10         }
11         grid[0][0][0] = true;
12         for(int i = 1;i<=s1.length();i++){
13             grid[i][0][i] = s1.charAt(i-1)==s3.charAt(i-1)&&grid[i-1][0][i-1];
14         }
15         for(int i = 1;i<=s2.length();i++){
16             grid[0][i][i] = s2.charAt(i-1)==s3.charAt(i-1)&&grid[0][i-1][i-1];
17         }
18         for(int i=1;i<=s1.length();i++){
19             for(int j=1;j<=s2.length();j++){
20                 for(int k=1;k<=s3.length();k++){
21                     grid[i][j][k] = (s1.charAt(i-1)==s3.charAt(k-1)&&grid[i-1][j][k-1])||(s2.charAt(j-1)==s3.charAt(k-1)&&grid[i][j-1][k-1]);
22                 }
23             }
24         }
25         return grid[s1.length()][s2.length()][s3.length()];
26     }

AC  748ms

继续思考,由于k!=i+j时grid[i][j][k]的值一定是false,因此这种情况没有意义,因此可以将k用i和j表示,这样就可以降维,将grid降维二阶矩阵。代码如下

 1 public boolean isInterleave(String s1, String s2, String s3) {
 2         boolean grid[][] = new boolean[s1.length()+1][s2.length()+1];
 3         if(s1.length()+s2.length()!=s3.length()){
 4             return false;
 5         }
 6         if(s1.equals("")){
 7             return s2.equals(s3);
 8         }else if(s2.equals("")){
 9             return s1.equals(s3);
10         }
11         grid[0][0] = true;
12         for(int i = 1;i<=s1.length();i++){
13             grid[i][0] = s1.charAt(i-1)==s3.charAt(i-1)&&grid[i-1][0];
14         }
15         for(int i = 1;i<=s2.length();i++){
16             grid[0][i] = s2.charAt(i-1)==s3.charAt(i-1)&&grid[0][i-1];
17         }
18         for(int i=1;i<=s1.length();i++){
19             for(int j=1;j<=s2.length();j++){
20                 for(int k=1;k<=s3.length();k++){
21                     grid[i][j] = (s1.charAt(i-1)==s3.charAt(i+j-1)&&grid[i-1][j])||(s2.charAt(j-1)==s3.charAt(i+j-1)&&grid[i][j-1]);
22                 }
23             }
24         }
25         return grid[s1.length()][s2.length()];
26     }

AC  660ms

posted @ 2014-05-29 14:25  秋风一片叶  阅读(133)  评论(0编辑  收藏  举报