leetcode_108 Interleaving String

161 篇文章 0 订阅

题目:

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

Example 1:

Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
Output: true

Example 2:

Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
Output: false

解法一:DFS 回溯法(暴力搜索)

用例:(TLE)

"bbbbbabbbbabaababaaaabbababbaaabbabbaaabaaaaababbbababbbbbabbbbababbabaabababbbaabababababbbaaababaa"
"babaaaabbababbbabbbbaabaabbaabbbbaabaaabaababaaaabaaabbaaabaaaabaabaabbbbbbbbbbbabaaabbababbabbabaab"
"babbbabbbaaabbababbbbababaabbabaabaaabbbbabbbaaabbbaaaaabbbbaabbaaabababbaaaaaabababbababaababbababbb
ababbbbaaaabaabbabbaaaaabbabbaaaabbbaabaaabaababaababbaaabbbbbabbbbaabbabaabbbbabaaabbababbabbabbab"

代码如下:

class Solution {
public:
    bool backtrace(string s1,string s2,string s3)
    {
        if(s1[0] == '\0' && s2[0] == '\0' && s3[0] =='\0')
        {
            return true;
        }
        if(s1[0] != s3[0] && s2[0] != s3[0])
            return false;
        if(s1[0] == s3[0] && s1[0] !='\0' && s2[0] != s3[0])
           if(backtrace(s1.substr(1),s2,s3.substr(1)))
               return true;
        if(s1[0] != s3[0] && s2[0] == s3[0] && s2[0] != '\0')
           if(backtrace(s1,s2.substr(1),s3.substr(1)))
               return true;
        if(s1[0] == s3[0] && s2[0] == s3[0])
        {
           if(backtrace(s1.substr(1),s2,s3.substr(1)) || backtrace(s1,s2.substr(1),s3.substr(1)))
               return true;
        }
        return false;
    }
    bool isInterleave(string s1, string s2, string s3) {
        
        return backtrace(s1,s2,s3);
    }
};

解法二:对解法一进行了优化,增减了memo[s1.length()][s2.length()] ,如果值 >= 0, 则说明已经计算过,直接使用计算过的值,节省了重复计算的时间

class Solution {
public:
    bool backtrace(string s1,int i,string s2,int j,string s3,int k,vector<vector<int> > &memo)
    {
        if(i == s1.length())
            return s2.substr(j) == s3.substr(k);
        if(j == s2.length())
            return s1.substr(i) == s3.substr(k);
        if(memo[i][j] >= 0)
            return memo[i][j] == 1 ? true : false;
        bool ans = false;
        if((s3[k] == s1[i] && backtrace(s1,i+1,s2,j,s3,k+1,memo)) || 
           (s3[k] == s2[j] && backtrace(s1,i,s2,j+1,s3,k+1,memo)))
        {
            ans = true;
        }
        memo[i][j] = ans ? 1 : 0;
        return ans;
    }
    bool isInterleave(string s1, string s2, string s3) {
        vector<vector<int> > memo(s1.length(),vector<int>(s2.length(),-1));
        return backtrace(s1,0,s2,0,s3,0,memo);
    }
};

 

解法三:BFS + queue + visited

queue只存储匹配的 i,j     visited标记已经访问过的i,j 

class Solution {
public:
    bool isInterleave(string s1, string s2, string s3) {
        if(s1.length() + s2.length() != s3.length())
            return false;
        vector<vector<bool> > visited(s1.length() + 1, vector<bool>(s2.length()+1,false));
        queue<vector<int> > Q;
        vector<int> vi = {0,0};
        Q.push(vi);
        while(!Q.empty())
        {
            vector<int> p = Q.front();
            Q.pop();
            if(visited[p[0]][p[1]])
                continue;
            if(p[0] == s1.length() && p[1] == s2.length())
                return true;
            if(p[0] < s1.length() && s1[p[0]] == s3[p[0] + p[1]])
            {    
                vector<int> v1 = {p[0] + 1, p[1]};
                Q.push(v1);
            }
            if(p[1] < s2.length() && s2[p[1]] == s3[p[0] + p[1]])
            {
                vector<int> v2 = {p[0],p[1] + 1};
                Q.push(v2);
            }
             visited[p[0]][p[1]] = true;
        }
        return false;
    }
};

解法四:动态规划

 bool isInterleave(string s1, string s2, string s3) {
    
    if(s3.length() != s1.length() + s2.length())
        return false;
    
    bool table[s1.length()+1][s2.length()+1];
    
    for(int i=0; i<s1.length()+1; i++)
        for(int j=0; j< s2.length()+1; j++){
            if(i==0 && j==0)
                table[i][j] = true;
            else if(i == 0)
                table[i][j] = ( table[i][j-1] && s2[j-1] == s3[i+j-1]);
            else if(j == 0)
                table[i][j] = ( table[i-1][j] && s1[i-1] == s3[i+j-1]);
            else
                table[i][j] = (table[i-1][j] && s1[i-1] == s3[i+j-1] ) || (table[i][j-1] && s2[j-1] == s3[i+j-1] );
        }
        
    return table[s1.length()][s2.length()];
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值