动态规划-字符串交叉问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_38169413/article/details/82557211

题目描述

给出三个队列 s1,s2,s3 ,判断 s3 是否是由 s1 和 s2 交叉得来。 如:s1 为 aabcc , s2 为 dbbca。 当 s3 为 aadbbcbcac 时,返回 true(即将 s1 拆成三部分: aa,bc,c 分别插入 s2 对应位置) 否则返回 false。

  • 输入

aabcc,dbbca,aadbbcbcac

  • 输出

true

  • 输入样例

aabcc,dbbca,aadbbcbcac
aabcc,dbbca,aadbbbaccc
a,b,ab
a,b,ba
a,b,ac
abc,bca,bcaabc
abc,bca,aabbcc

  • 输出样例

true
false
true
true
false
true
false

解题思路

本题使用动态规划算法,**dp[i][j]**表示使用s1的前i个字符和s2的前j个字符组成s3的前i+j个字符的可能性。很显然,dp[0][0] = true;,动态数组初始化为:

for (int i = 1; i <= s1.length(); i++)
	dp[i][0] = dp[i - 1][0] && (s1[i - 1] == s3[i - 1]);
for (int i = 1; i <= s2.length(); i++)
	dp[0][i] = dp[0][i - 1] && (s2[i - 1] == s3[i - 1]);

递归公式为:

int k = i + j;
if (s1[i - 1] == s3[k - 1])
	dp[i][j] = dp[i][j] || dp[i - 1][j];
if (s2[j - 1] == s3[k - 1])
	dp[i][j] = dp[i][j] || dp[i][j - 1];

参考代码

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <string>
using namespace std;

bool isValid(string s1, string s2, string s3) {
	if (s3.length() != s1.length() + s2.length())
		return false;
	//动态数组,表示s1的前i个字符和s2的前j个字符组成s3的前i+j个字符的可能
	vector<vector<bool> > dp(s1.length() + 1, vector<bool>(s2.length() + 1, false));
	dp[0][0] = true;
	for (int i = 1; i <= s1.length(); i++)
		dp[i][0] = dp[i - 1][0] && (s1[i - 1] == s3[i - 1]);
	for (int i = 1; i <= s2.length(); i++)
		dp[0][i] = dp[0][i - 1] && (s2[i - 1] == s3[i - 1]);

	for (int i = 1; i <= s1.length(); i++) {
		for (int j = 1; j <= s2.length(); j++) {
			int k = i + j;
			if (s1[i - 1] == s3[k - 1])
				dp[i][j] = dp[i][j] || dp[i - 1][j];
			if (s2[j - 1] == s3[k - 1])
				dp[i][j] = dp[i][j] || dp[i][j - 1];
		}
	}

	return dp[s1.length()][s2.length()];
}

int main() {
	string s1, s2, s3, s;
	while (cin >> s) {
		s1 = s.substr(0, s.find(','));
		s = s.substr(s.find(',') + 1);
		s2 = s.substr(0, s.find(','));
		s3 = s.substr(s.find(',') + 1);
		if (isValid(s1, s2, s3))
			cout << "true" << endl;
		else
			cout << "false" << endl;
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_38169413/article/details/82557211