动态规划-字符串的交错组成

字符串交错组成

题目描述:

对于三个字符串A,B,C。我们称C由A和B交错组成当且仅当C包含且仅包含A,B中所有字符,且对应的顺序不改变。请编写一个高效算法,判断C串是否由A和B交错组成。

给定三个字符串A,B和C,及他们的长度。请返回一个bool值,代表C是否由A和B交错组成。保证三个串的长度均小于等于100。

测试样例:

"ABC",3,"12C",3,"A12BCC",6
返回:true

分析思路:

构造一个(M+1)*(N+1)的矩阵dp:

  1. dp[0][0]=true.aim为空时可以由str1和str2的空字符串组成
  2. dp[i][0]表示aim[0…i-1]能否由str1[0……i-1]组成,若可以则dp[i][0]=true,反之则为false
  3. dp[0][j]表示aim[0…j-1]能否由str2[0……j-1]组成,若可以则dp[0][j]=true,反之则为false
  4. 其他位置(i,j),dp[i][j]的值:

dp[i-1][j]代表aim[i+j-2]能否被str1[0…i-2]和str2[0…j-1]交错组成,若可以,以及str1[i-1]等于aim[i+j-1],则dp[i][j]=true,反之则为false

dp[i][j-1]代表aim[i+j-2]能否被str1[0…i-1]和str2[0…j-2]交错组成,若可以,以及str2[j-1]等于aim[i+j-1],则dp[i][j]=true,反之则为false

若前两种情况都不满足,则dp[i][j]=false

代码实现

#include<bits/stdc++.h>
using namespace std;

class Solution
{
public:
	bool isInterleave(string s1, string  s2, string s3)
	{
		size_t len1, len2;
		len1 = s1.length();
		len2 = s2.length();

		if (len1 + len2 != s3.length())
			return false;
		vector<vector<bool>> dp;//定义变量
		dp.resize(len1 + 1, vector<bool>(len2 + 1, false));//分配空间

		dp[0][0] = true;//aa ab aaba
 		for (int i = 0; i <= len1; i++)
			for (int j = 0; j <= len2; j++)
			{
				if (i == 0 && j == 0)
					continue;

				if (i > 0) {
					if (s1[i - 1] == s3[i + j - 1]) {
						 dp[i][j] = dp[i][j] || dp[i - 1][j];
					}
				}
				if (j > 0) {
					if (s2[j - 1] == s3[i + j - 1]) {
						dp[i][j] = dp[i][j] || dp[i][j - 1];
					}
				}
			}
		bool result = dp[len1][len2];
		return result;
	}
};

int main()
{
	Solution S;
	string s1 = "aa";
	string s2 = "ab";
	string s3 = "aaba";
	
	bool ans = S.isInterleave(s1, s2, s3);
	if (ans) cout << "true" << endl;
	else     cout << "false" << endl;
	
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值