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.

#include <iostream>
#include <string>
#include <vector>

/**
Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.

For example,
Given:
s1 = "aabcc",
s2 = "dbbca",

      a  a  b  c  c
    d  
    b
    b
    c
    a

When s3 = "aadbbcbcac", return true.
When s3 = "aadbbbaccc", return false.
思路:把s1和s2理解成图,然后进行遍历
    a -> a - > b -> c - >c
     
         结点之间全联通 

    d -> b -> b -> c - > a
   DFS其实就是暴力的思路来求解,所以在大数据不能AC
   DFS的复杂度是:最坏情况下遍历了所有的边 M和N的指数相关,如果相对于M来说,N^M 爆炸级别的遍历 所以明显里面包含了很多dp的节奏
   实际情况是,每次进去之前都会判断,相当于做了 tuning.

   这个DFS也可以用存储格的思路减少重复的计算

@ihasleetcode 给出了dp的解决办法
dp[i,j] = whether s3[i+j] can be interleaved by s1[0,i] and s2[0,j]

dp[i,j] = dp[i-1,j] && s2[i+j -1] == s1[i-1] || dp[i,j-1] && s3[i + j -1] == s2[j - 1]

*/

using namespace std;

class Solution {
public:
    //从前往后找就是在搜素
    bool dfs(string s1, int pos1, string s2, int pos2, string s3){
        if (pos1 == s1.size() && pos2 == s2.size() && pos1 + pos2 == s3.size()){
            return true;
        }
        bool ans;
        if (pos1 < s1.size() && s1[pos1] == s3[pos1 + pos2]){
            ans = dfs(s1,pos1 + 1, s2, pos2, s3);
            if (ans) return ans;
        }
        if (pos2 < s2.size() && s2[pos2] == s3[pos1 + pos2]){
            ans = dfs(s1,pos1, s2, pos2+ 1, s3);
            if (ans) return ans;
        }    
        
        return false;
    }
    //从后往前找 dfs+cache
    bool dfs_cache(string s1,int p1, string s2, int p2){
        
    }
    bool isInterleave(string s1, string s2, string s3) {
           //return dfs(s1,0,s2,0,s3,0);
          if (s1.empty()){
                return s2 == s3;
          }
          if (s2.empty()){
                return s1 == s3;    
          }
          return dp(s1,s2,s3);
    }
    bool dp(string s1, string s2, string s3){
       
        if (s3.size() != s1.size() + s2.size()) {
            return false;
        }
    
        vector<vector<bool> > dp;
        dp.resize(s1.size() + 1);
        for(int i = 0; i < s1.size() + 1; i++){
            dp[i].resize(s2.size() + 1,false);
            dp[i][0] = true;
        }
        
        for(int i = 0; i <= s1.size(); i++){
            for(int j = 0; j <= s2.size(); j++){
                if (i && s3[i + j -1] == s1[i -1] && dp[i-1][j]){
                    dp[i][j] = true;
                }
                if (j && s3[i + j -1] == s2[j -1]  && dp[i][j-1]){
                    dp[i][j] = true;
                }
            }
        }
        return dp[s1.size()][s2.size()];
    }

        //可以进一步做压缩,2个变量就足够
        bool dp3(string s1, string s2, string s3) {
            // Start typing your C/C++ solution below
            // DO NOT write int main() function    
            if (s3.size() != s1.size() + s2.size()) {
                return false;
            }
            vector<bool> dp;
            dp.resize(s2.size() + 1,false);
            int i ,j;
            dp[0] = true;
            for (i = 0; i <= s1.size(); ++i) {
              //第一行从1开始,以后从0开始?
                for (j = i?0:1; j <= s2.size(); ++j) {
                    dp[j] = (i && dp[j] && (s1[i - 1] == s3[i + j - 1]))
                     || (j && dp[j - 1] && (s2[j - 1] == s3[i + j - 1]));
                }
            }
            return dp[s2.size()];    
        }
    
    //2个变量的版本

};

using namespace std;
int main(int argc, char *argv[]) {
    Solution sol;
    string s1 = "aabcc";
    string s2 = "dbbca";
    string s3 = "aadbbcbcac";
    string s4 = "aadbbbaccc";
    cout << sol.isInterleave(s1,s2,s3);
}

 

posted @ 2013-08-27 22:50  一只会思考的猪  阅读(511)  评论(0编辑  收藏  举报