leetcode之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.

这道题是昨天有道的最后一道笔试题,可惜不会,当时甚至连题意都没能理解清楚,现在记录下这道题的两种解法。

解法一:可以采用递归调用,即依次遍历字符串S3,判断当前字符是来自s1还是来自s2,这里存在的问题是如果当前字符与s1和s2的当前字符都相等的话需要两边都进行尝试,所以其复杂度比较高(为O(mnk)),在leetcode上运行超大字符串时出现超时现象。

 bool isInterleave(string s1, string s2, string s3) {
		if(s1.length() + s2.length() != s3.length())
			return false;
		return rec(s1,0,s2,0,s3,0);
    }
	bool rec(string s1,int p1,string s2,int p2,string s3,int p3){
		if(p3 == s3.length())
			return true;
		if(p1 == s1.length())
			return s2.substr(p2) == s3.substr(p3);
		if(p2 == s2.length())
			return s1.substr(p1) == s3.substr(p3);
		if(s1[p1] == s3[p3] && s2[p2] == s3[p3])
			return rec(s1,p1+1,s2,p2,s3,p3+1) || rec(s1,p1,s2,p2 + 1,s3,p3+1);
		if(s1[p1] == s3[p3])
			return rec(s1,p1+1,s2,p2,s3,p3+1);
		if(s2[p2] == s3[p3])
			return rec(s1,p1,s2,p2 + 1,s3,p3+1);
		return false;
	}

解法二:采用动态规划思想,这里需要创建(m+1)*(n+1)的二维矩阵,其中m为s1的长度,n为s2的长度,矩阵vv[i[j]表示已s1中前i个字符和s2中前j个字符能否组成s3中前i+j-1个字符。针对矩阵中的每一个单元,都需要判断两次,(画出二维矩阵图后比较容易理解),这种算法的时间复杂度是O(m*n)。

bool isInterleave(string s1, string s2, string s3) {
		int len1 = s1.length();
		int len2 = s2.length();
		int len3 = s3.length();
		if(len1 + len2 != len3)
			return false;
		vector<vector<int>>vv(len1 + 1);
		for(int i = 0; i <len1 + 1; i++ ){
		      vv[i] = vector<int>(len2 + 1);
		}
		vv[0][0] = 1;
		for(int i = 1 ; i < len1 + 1; i++)
		{
			if(vv[i-1][0] == 1 && s1[i - 1] == s3[i -1])
				vv[i][0] = 1;
			else
				vv[i][0] = 0;
		}
		for(int j = 1; j < len2 + 1; j++){
		    if(vv[0][j - 1] == 1 && s2[j - 1] == s3[j - 1])
				vv[0][j] = 1;
			else
				vv[0][j] = 0;
		}
		for(int i = 1; i < len1+ 1;i ++){
			for(int j = 1; j < len2 + 1;j++){
			    if(s1[i - 1] == s3[i + j - 1] && vv[i - 1][j] ==1 ||s2[j-1] == s3[i + j - 1] && vv[i][j - 1] == 1)
					vv[i][j] =1;
				else
					vv[i][j] = 0;
			}
		}
		return vv[len1][len2];
		//return rec(s1,0,s2,0,s3,0);

    }


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值