题目

交叉字符串

给出三个字符串:s1、s2、s3,判断s3是否由s1和s2交叉构成。

样例

比如 s1 = "aabcc" s2 = "dbbca"

    - 当 s3 = "aadbbcbcac",返回  true.

    - 当 s3 = "aadbbbaccc", 返回 false.

挑战

要求时间复杂度为O(n^2)或者更好

解题

交叉比较,不能够AC

参考这里的程序,直接运行原程序,在自己的基础上进行修改运行到78%测试数据的时候还是错了

这里给了几种失败的方法

下面只有选择动态规划来解题了

动态规划矩阵matched[l1][l2]表示s1取l1长度(最后一个字母的pos是l1-1),s2取l2长度(最后一个字母的pos是l2-1),是否能匹配s3的l1+12长度。

那么,我们有

matched[l1][l2] = s1[l1-1] == s3[l1+l2-1] && matched[l1-1][l2] || s2[l2 - 1] == s3[l1+l2-1] && matched[l1][l2-1]

边界条件是,其中一个长度为0,另一个去匹配s3.

Java

public class Solution {
    /**
     * Determine whether s3 is formed by interleaving of s1 and s2.
     * @param s1, s2, s3: As description.
     * @return: true or false.
     */
    public boolean isInterleave(String s1, String s2, String s3) {
        // write your code here
        if(s1.length() + s2.length() != s3.length())
            return false;
        // if(s1.equals("")&& s2.equals(s3))
        //     return true;
        // if(s2.equals("")&&s1.equals(s3))
        //     return true;
        boolean[][] matched= new boolean[s1.length()+1][s2.length()+1];
        matched[0][0]= true;
        for(int i1=1;i1<= s1.length(); i1++){
            if(s3.charAt(i1-1) == s1.charAt(i1-1))
                matched[i1][0] = true;
        }
        for(int i2= 1;i2<= s2.length();i2++){
            if(s3.charAt(i2-1) == s2.charAt(i2-1))
                matched[0][i2] = true;
        }
        for(int i1=1;i1<=s1.length(); i1++){
            char c1 = s1.charAt(i1-1);
            for(int i2 = 1;i2<= s2.length();i2++){
                int i3 = i1+ i2;
                char c2 = s2.charAt(i2- 1);
                char c3 = s3.charAt(i3 -1);
                if(c1 == c3)
                    matched[i1][i2] =matched[i1][i2] || matched[i1-1][i2];
                if( c2== c3)
                    matched[i1][i2] = matched[i1][i2] || matched[i1][i2-1];
                    
            }
        }
        return matched[s1.length()][s2.length()];
    }
}
Java Code

 Python

class Solution:
    """
    @params s1, s2, s3: Three strings as description.
    @return: return True if s3 is formed by the interleaving of
             s1 and s2 or False if not.
    @hint: you can use [[True] * m for i in range (n)] to allocate a n*m matrix.
    """
    def isInterleave(self, s1, s2, s3):
        # write your code here
        len1 = len(s1)
        len2 = len(s2)
        len3 = len(s3)
        if len1+len2 != len3:
            return False
        # len1 = 2
        # len2 = 3
        matched = [[False for i in range(len2+1)] for j in range(len1+1)]
        
        matched[0][0] = True
        # print matched
        for i in range(1,len1+1):
            if s1[i-1]==s3[i-1]:
                matched[i][0] = True
        for i in range(1,len2+1):
            if s2[i-1]==s3[i-1]:
                matched[0][i] = True
        for i1 in range(1,len1+1):
            for i2 in range(1,len2+1):
                i3 = i1 + i2
                if s1[i1-1]==s3[i3-1]:
                    matched[i1][i2] = matched[i1][i2] or matched[i1-1][i2]
                if s2[i2-1]==s3[i3-1]:
                    matched[i1][i2] = matched[i1][i2] or matched[i1][i2-1]
                    
        return matched[len1][len2]
Python Code