Interleaving String

本文介绍了一种用于判断一个字符串是否能由另外两个字符串交织而成的有效算法。通过递归和迭代两种方式实现,并详细解析了如何运用动态规划解决此问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给定3个字符串(s1,s2,s3),看s3是否是有s1和s2通过交织可以得到。
s1 = "aabcc",

s2 = "dbbca",

When s3 = "aadbbcbcac", return true.
When s3 = "aadbbbaccc", return false.

思路:这题很容易想到扫描算法,但是试验过后发现顺序很难判断。于是就用到了动态规划的思想。设函数:
bool isInterleaving(string &s1, int len1, string &s2, int len2, string &s3, int len3);
则,可以得到

isInterleaving(s1,len1,s2,len2,s3,len3) 
= (s3.lastChar == s1.lastChar) && isInterleaving(s1,len1 - 1,s2,len2,s3,len3 - 1)
||(s3.lastChar == s2.lastChar) && isInterleaving(s1,len1,s2,len2 - 1,s3,len3 - 1)

由于len3 === len1 + len2,所以这个问题里面实际上存在着两个变量,是一个二维动态规划题目。

代码:

递归的形式,容易导致超时

bool isInterleave(string s1, string s2, string s3) { // Start typing your C/C++ solution below // DO NOT write int main() function int pr1=0; int pr2=0; int index=0; bool leftIs=false; bool rightIs=false; if (s3.size()==0&&s1.size()==0&&s2.size()==0) return true; if (s3[index]==s1[pr1]) leftIs=isInterleave(s1,s2,s3,pr1+1,pr2,index+1); if (s3[index]==s2[pr2]) rightIs=isInterleave(s1,s2,s3,pr1,pr2+1,index+1); return leftIs||rightIs; } bool isInterleave(string & s1,string & s2, string & s3,int pr1,int pr2, int index) { bool leftIs=false; bool rightIs=false; if (s3.size()==index&&s1.size()==pr1&&s2.size()==pr2) return true; if (s3[index]==s1[pr1]) leftIs=isInterleave(s1,s2,s3,pr1+1,pr2,index+1); if (s3[index]==s2[pr2]) rightIs=isInterleave(s1,s2,s3,pr1,pr2+1,index+1); return leftIs||rightIs; }

只有迭代的形式,用24ms过大测试集合

bool isInterleave(string s1, string s2, string s3) {
        if(s3.size() != s1.size() + s2.size())
            return false;
        //create indicator
        vector<vector<bool> > match(s1.size() + 1, vector<bool>(s2.size() + 1, false));
        //initialization the first row and the first column
        match[0][0] = true;
        for( int l1 = 1; l1 <= s1.size(); ++ l1 ) {
            char c1 = s1[l1 - 1];
            char c3 = s3[l1 - 1];
            if (c1 == c3) {
                match[l1][0] = true;
            } else 
                break;
        }
        for( int l2 = 1; l2 <= s2.size(); ++ l2 ) {
            char c2 = s2[l2 - 1];
            char c3 = s3[l2 - 1];
            if (c2 == c3) {
                match[0][l2] = true;
            } else 
                break;
        }
        //work through the rest of matrix using the formula
        for( int l1 = 1; l1 <= s1.size(); ++ l1 ) {
            char c1 = s1[l1 - 1];
            for( int l2 = 1 ; l2 <= s2.size() ; ++ l2 ) {
                char c2 = s2[l2 - 1];
                int l3 = l1 + l2;
                char c3 = s3[l3 - 1];
                if (c1 == c3) {
                    match[l1][l2] = match[l1 - 1][l2] || match[l1][l2];
                }
                if (c2 == c3) {
                    match[l1][l2] = match[l1][l2 - 1] || match[l1][l2];
                }
            }
        }
        //the last element is the result
        return match[s1.size()][s2.size()];
    }







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值