[leetcode] 97. 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.

这道题是判断字符串是否由另两个字符串通过字符交织生成,题目难度为Hard。

最直观的想法是通过回溯法来逐个检查s3中字符,通过记录下s1和s2中比对位置来比对s3中当前字符,如果s3中当前字符和s1比对位置字符相同,将s1比对位置加1继续比对s3中下一字符,s2同理,如果s3中当前字符和s1、s2比对位置字符都不同则向上回溯。可惜提交之后超时了,这里就不列出代码了。

回溯法行不通,可以从后向前思考,假设s1长度为m,s2长度为n,拿s3[m+n-1]和s1[m-1]、s2[n-1]进行比对,分以下三种情况:

  • s3[m+n-1] == s1[m-1],如果s3前m+n-1个字符组成的字符串可以由s1前m-1个字符组成的字符串和s2交织生成,返回true;
  • s3[m+n-1] == s2[n-1],如果s3前m+n-1个字符组成的字符串可以由s1和s2前n-1个字符组成的字符串交织生成,返回true;
  • s3[m+n-1] != s1[m-1] && s3[m+n-1] != s2[n-1],s3不能由s1和s2交织生成。

这里用isMatch[i][j]表示s1前i个字符组成的字符串和s2前j个字符组成的字符串是否能够交织生成s3前i+j个字符组成的字符串,通过以上分析可以得出isMatch[i][j] = (isMatch[i-1][j] && s1[i-1]==s3[i+j-1]) || (isMatch[i][j-1] && s2[j-1]==s3[i+j-1]),而isMatch[0][0] == true(三个字符串都是空字符串时是显然的),这样通过动态规划就能够递推出isMatch[m][n],即最终结果。具体代码:

class Solution {
public:
    bool isInterleave(string s1, string s2, string s3) {
        int sz1 = s1.size(), sz2 = s2.size(), sz3 = s3.size();
        if(sz1 + sz2 != sz3) return false;
        vector<vector<char>> isMatch(sz1+1, vector<char>(sz2+1, 0));
        isMatch[0][0] = 1;
        for(int i=0; i<=sz1; ++i) {
            for(int j=0; j<=sz2; ++j) {
                if(i && isMatch[i-1][j]) isMatch[i][j] |= (s1[i-1]==s3[i+j-1]);
                if(j && isMatch[i][j-1]) isMatch[i][j] |= (s2[j-1]==s3[i+j-1]);
            }
        }
        return isMatch[sz1][sz2];
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值