交错字符串——动态规划

题目描述:

给定三个字符串A, B, C,判断C是否由A和B交错构成。交错构成的意思是,对于字符串C,可以将其每个字符标记为A类或B类,使得我A类的每个字符顺序构成了A字符串,B类的每个字符顺序构成了B字符串。如:对于A=”rabbit” B=”mq”, ”rabmbitq”是由A和B交错构成的,但”rabbqbitm”不是由A和B交错构成。

解题思路:

1、直接顺序比较,从C中依次拿掉A,看剩下的是不是等于B,若是则返回true,否则,返回false. 但是如果A和B中有相同的字符,则这种方法会出错。

例如,A=“aa”, B=“ab”,C=“aaba”  这种情况下,上述这种方法会返回false,但实际上它是true。 因此这种方法不可行。

2、采用动态规划的方法

定义状态:dp[i][j] 代表是A的前i个字符与C中匹配,B中前j个字符与C中匹配.

递推的比较过程中如果知道s1,s2上的指针p,q的情况,s3上这个指针肯定在p+q的位置。利用这个结论,就可以设计出O(m1*m2)的DP方案。

执行操作分为两步,分别判断:

A[i-1] == C[i+j-1]  为真,则 dp[i][j] = dp[i][j] || dp[i-1][j]

B[j-1] == C[i+j-1] 为真,则dp[i][j] = dp[i][j] || dp[i][j-1]

最后返回:dp[i][j],此时,i=s1.lenth(),  j=s2.length()

参考代码:

#include"iostream"
#include"vector"
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;
		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.isInter(s1, s2, s3);
	if (ans)
		cout << "true" << endl;
	else
		cout << "false" << endl;

}

这道题目跟最长公共子序列有点相似,思路类似,稍作变换.

LCS是判断一个串,这个题目是同时判断两个串。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-06 14:21:07

交错字符串——动态规划的相关文章

nyist oj 37 回文字符串 (动态规划经典)

回文字符串 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"aba".当然,我们给你的问题不会再简单到判断一个字符串是不是回文字符串.现在要求你,给你一个字符串,可在任意位置添加字符,最少再添加几个字符,可以使这个字符串成为回文字符串. 输入 第一行给出整数N(0<N<100) 接下来的N行,每行一个字符串,每个字符串长度不超过1000. 输出 每行输出所需添加的最少字符

[leetcode] 97. 交错字符串

97. 交错字符串 题不难,dfs加回溯即可.实际上就是暴力搜索,穷举所有选择路径. 以s3的每一个字母做一个状态,就面临两个抉择,选s1还是选s2.选s1路不通的话,回溯回来改选s2即可. class Solution { // 状态:String s1, String s2, String s3, int p, int q, int i // p为当前s1的下标指针,q为当前s2的下标指针,i为s3的 boolean dfs(String s1, String s2, String s3,

leetCode 97.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. 思路:此题刚开始有点想当然了

LeetCode(97):交错字符串

Hard! 题目描述: 给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的. 示例 1: 输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac" 输出: true 示例 2: 输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc" 输出: false 解题思路:

97. 交错字符串

题目描述: 给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的. 示例 1: 输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"输出: true示例 2: 输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"输出: false 思路: 设dp[i][j]表示

(字符串动态规划)一个字符串变成另一个字符串的步骤数

题目: 给定两个字word1和word2,找到将word1转换为word2所需的最小步骤数. (每个操作计为1步). 您对单词允许以下3种操作: a)插入字符 b)删除字符 c)替换字符 思路: dp[i][j]指把word1[0..i - 1]转换为word2[0..j - 1] 的最小操作数. 边界条件: dp[i][0] = i; 从长度为 i 的字符串转为空串 要删除 i 次 dp[0][j] = j. 从空串转为长度为 j 的字符串 要添加 j 次 一般情况: 如果word[i - 1

Luogu2543[AHOI2004]奇怪的字符串 (动态规划 LCS)

04年的省选这么water吗,开个滚动数组算了 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define R(a,b,c) for(register int a = (b); a <= (c); ++ a) #define nR(a,b,c) for(register int a = (b);

我的 NOIP 2015

2015,OI 生涯最后一个完整的赛季 从今年的Noip就已经开始了.说起来自己也是从七年级升八年级的暑假就开始接触OI了,不过和许多人一样,一直都是”混“,不知道自己到底在干什么,也没用什么功,每次noip都是考前一两个月才想起来要学OI,然后胡乱刷上几道题,就这么草草参加联赛,每次都是很虚地参加比赛,这次也是,其实到头来都是自己水平太差了,感觉好像考前也挺重视的,实际上也没什么行动,肚子里没点题目,手上怎么能熟练,上了考场紧张也是自然的,所以今年也就因为这紧张的心情Day1 也没发挥好,当然

Topcoder SRM 648 (div.2)

第一次做TC全部通过,截图纪念一下. 终于蓝了一次,也是TC上第一次变成蓝名,下次就要做Div.1了,希望div1不要挂零..._(:зゝ∠)_ A. KitayutaMart2 万年不变的水题. #include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<set> #include<map&