待字闺中之interleave字符串分析

Interleaving String

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.

这个题目中,并没有说明a和b中是否有相同的字符,这个直接影响了最终的解法。所以,大家在面试的过程中,要和面试官进行交互,弄清楚之后再动手。我们这里对于是否有相同的字符都给予分析。希望对大家有所帮助。

a和b没有相同字符的情况

这个情况处理起来比较简单,逐个字符遍历c字符串,首先处理第一个字符,将其与a中的字符匹配,如果没有匹配,则与b中的字符逐个匹配,如果没有匹 配,则返回false;如果a中或者b中有一个字符和c的第一个字符匹配上了,则如上考虑第二个字符,与c的第一个字符匹配上的字符串,也考虑第二个字 符,依次类推。直到c遍历完,这时,如果a和b还有字符没有遍历,也返回false,都遍历完毕,返回true。代码如下:

bool interleave_diff(const char* a,const char* b,const char* c)
{
	int lenA = strlen(a),lenB = strlen(b),lenC = strlen(c);
	if(lenA + lenB != lenC)return false;
	int i = 0,j = 0,k = 0;
	while(c[k] != '\0')
	{
		if(a[i] == c[k]) i++;
		else if(b[j] == c[k]) j++;
		else return false;
		k++;
	}
	if(a[i] != '\0' || b[j] != '\0')return false;
	return true;
}

a和b有相同字符的情况

上面的算法,不能够处理a和b中有相同字符的情况,例如a="XXY",b="XXZ",c="XXZXXY"。如果要处理,有相同字符的情况也是 比较直接的。有相同的出现,如果都匹配了c中的字符,则两种匹配分别都考虑,只要有一个返回true,整个算法就返回true。

所以,下面介绍一个动态规划的解法。一个问题能够用动态规划来解的一个前提是:要有重复的子 问题。这样把子问题的解存储起来,后面重复利用才可以提高算法的效率。这个问题有子问题么?考虑一个极端的例 子:a="XXX",b="XXX",c="XXXXXX"。子问题,显然存在。再不然,画出递归树,就很明了了。

我们采用二维表来存储子问题的结果,dp[i][j]如果为true,则表示c[0..i+j-1]是a[0..i-1]和b[0..j-1]的interleave字符串。算法实现的过程于上面的递归类似:

class Solution {
public:
    bool isInterleave(string s1, string s2, string s3) {
    	int length1 = s1.size(),length2 = s2.size(),length3 = s3.size(),i = 0,j = 0;
    	if(length1 + length2 != length3)return false;
    	vector<vector<bool> > dp(length1+1);
    	for(i = 0;i <= length1;++i)
    	{
    		vector<bool> tmp(length2+1,false);
    		dp[i] = tmp;
    	}
    	dp[0][0] = true;
    	for(i = 0; i <= length1;++i)
    	{
    		for(j = 0;j <= length2;++j)
    		{
    			if(i > 0 && s1[i-1] == s3[i+j-1])dp[i][j] = dp[i][j] || dp[i-1][j];
    			if(j > 0 && s2[j-1] == s3[i+j-1])dp[i][j] = dp[i][j] || dp[i][j-1];
    		}
    	}
    	return dp[length1][length2];
    }

};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值