Thursday, October 24, 2013

Interleaving String [Leetcode]

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.

Solution: DP again. Transitive function is: dp(i,j) = (s3[i+j]==s1[i] && dp(i-1,j)) OR (s3[i+j]==s2[j] && dp(i,j-1)), where dp(i,j) means s3[1,...,i+j] can be formed by interleaving s1[1,...,i] and s2[1,...,j]. (for the ease of description, we assume the strings use 1-based indexing).

class Solution {
public:
    bool isInterleave(string s1, string s2, string s3) {
        // Note: The Solution object is instantiated only once and is reused by each test case.   
        int l1 = s1.size(), l2=s2.size(), l3=s3.size();
        if(l1+l2!=l3) return false;
        if(l1==0) return s3==s2;
        if(l2==0) return s3==s1;
        vector<vector<int>> cache(l1+1, vector<int>(l2+1, 0));
       
        for(int i=0; i<=l1; ++i)
            for(int j=0; j<=l2; ++j){
                if(i==0 && j==0)
                    cache[i][j]=1;
                else if(i==0 && s3[j-1]==s2[j-1] && cache[i][j-1]){
                    cache[i][j]=cache[i][j-1];
                }
                else if(j==0 && s3[i-1]==s1[i-1] && cache[i-1][j]){
                    cache[i][j]=cache[i-1][j];
                }
                else
                    cache[i][j]= (s3[i+j-1]==s2[j-1] && cache[i][j-1]) || (s3[i+j-1]==s1[i-1] && cache[i-1][j]);
            }
        return cache.back().back();
    }
}; 

The following implementation is based on one-dimensional cache [the following code can be further optimized, but I do not want to do it for clarity].

class Solution {
public:
    bool isInterleave(string s1, string s2, string s3) {
        // Note: The Solution object is instantiated only once and is reused by each test case.    
        int l1 = s1.size(), l2=s2.size(), l3=s3.size();
        if(l1+l2!=l3) return false;
        if(l1==0) return s3==s2;
        if(l2==0) return s3==s1;
        vector<int> cache(l2+1, 0);
        
        for(int i=0; i<=l1; ++i)
            for(int j=0; j<=l2; ++j){
                if(i==0 && j==0)
                    cache[j]=1;
                else if(i==0 && s3[j-1]==s2[j-1] && cache[j-1]){
                    cache[j]=cache[j-1];
                }
                else if(j==0 && s3[i-1]==s1[i-1] && cache[j]){
                    cache[j]=cache[j];
                }
                else
                    cache[j]= (s3[i+j-1]==s2[j-1] && cache[j-1]) || (s3[i+j-1]==s1[i-1] && cache[j]);
            }
        return cache.back();
    }
};

No comments:

Post a Comment