Given three strings: s1, s2, s3, determine whether s3 is formed by the interleaving of s1 and s2.

Example

For s1 = "aabcc", s2 = "dbbca"

  • When s3 = "aadbbcbcac", return true.
  • When s3 = "aadbbbaccc", return false.
Challenge

O(n2) time or better.

标签

 动态规划  字符串处理

解题:

1. 错解:最初,自己通过思考想出了一个解决方案。就是从字符串s3中抽取顺序抽取出字符串s2的所有字符,将s3中剩下的字符与s2进行比较,如果相等,那么就返回true,否则返回false。依照这种思路,最终通过一些修改,也只能达到66%正确,很可能是方案覆盖不完整。比如测试用例:aa,ab,abaa,就过不了。当s1,s2同时匹配的时候,这里存在一个策略问题。

代码:

class Solution {
public:
/*
* Determine whether s3 is formed by interleaving of s1 and s2.
* @param s1, s2, s3: As description.
* @return: true of false.
/
bool isInterleave(string s1, string s2, string s3) {
// write your code here
//第一步还是理解问题,什么是交错字符串,然后根据特点想出解决方法; */
bool isInterleave(string s1, string s2, string s3) {
int a=s1.size(),b=s2.size(),c=s3.size();
int count=;
int num=-;
int m[c];
string s;
if(a==){
return s2==s3;
}
if(b==){
return s1==s3;
} for(int i=;i<c;i++){
m[i]=;
}
for(int i=;i<a;i++){
for(int j=;j<c;j++){
if(m[j]&&(s1[i]==s3[j])){
m[j]=;
++count;
break;
}
}
}
num=c-count;
int k=-;
if((count==a)&&(num==b)){ for(int i=;i<b;i++){
if(k==c-){
break;
}
for(int j=;j<c;j++){
if(m[j]&&(s2[i]==s3[j])){
num=num-;
k=j;
break;
}
}
}
if(num==){
return true;
}
else{
return false;
} /*for (int i=0;i<num;i++){
for(int j=0;j<c;j++){
if(m[j]!=0){
s[i]=s3[j];
}
}
}
return s.compare(s2);
*/
} else{
return false;
}
}
};

2. 正解:正解就是二维动态规划

分析:两个字符串的问题,大部分都可以用matched[i][j]表示第一个字符串前i个字符第二个字符串前j个字符的匹配情况来解决。

在这里,令动态规划矩阵为matched[l1][l2]表示s1取l1长度(最后一个字母的pos是l1-1),s2取l2长度(最后一个字母的pos是l2-1),是否能匹配s3的l1+12长度。

那么,我们有:
matched[l1][l2] = s1[l1-1] == s3[l1+l2-1] && matched[l1-1][l2] || s2[l2 - 1] == s3[l1+l2-1] && matched[l1][l2-1]

解释:如果对于第三个字符串的前l1+l2个元素  和 第一个字符串的前l1个元素和第二个字符串的前l2个元素能满足要求的话,那么就有两种情况:

(1)第三个字符串的最后一个元素s3[l1+l2-1],要么等于第一个字符串的最后一个元素s1[l1-1],并且matched[l1-1][l2]也满足要求。

(2)第三个字符串的最后一个元素s3[l1+l2-1],要么等于第二个字符串的最后一个元素s2[l2 - 1],并且matched[l1][l2-1]也满足要求。

这就是动态规划,递归的思想。

代码如下:

折腾了很久,还是有问题:

自己根据动态规划写的:

达到80% 正确,追究原因,因为定义的bool型的二维数组有问题;

class Solution {
public:
/**
* Determine whether s3 is formed by interleaving of s1 and s2.
* @param s1, s2, s3: As description.
* @return: true of false.
*/
bool isInterleave(string s1, string s2, string s3) {
// write your code here
// 先写出最基本的条件; if(s3.length()!=s1.length()+s2.length()){
return false;
} bool matched[s1.length()+][s2.length()+];//布尔类型初始值是0,也就是false; matched[][]=true;
for(int j=;j<s2.length();j++){ //这里也有点问题,要严格按照递归来编码。
if(s3.substr(,j)==s2.substr(,j)){
matched[][j+]=true;
}
}
for(int i=;i<s1.length();i++){ //这里也有点问题,要严格按照递归来编码。
if(s3.substr(,i)==s1.substr(,i)){
matched[i+][]=true;
}
} for(int i=;i<s1.length()+;i++){
for(int j=;j<s2.length()+;j++){
if((s3[i+j-]==s1[i-]&&matched[i-][j])||(s3[i+j-]==s2[j-]&&matched[i][j-]))
{
matched[i][j]=true;
} }
}
return matched[s1.length()][s2.length()];
}
};

别人正确的:C++

class Solution {
public:
/**
* Determine whether s3 is formed by interleaving of s1 and s2.
* @param s1, s2, s3: As description.
* @return: true of false.
*/
bool isInterleave(string s1, string s2, string s3) {
// write your code here
if(s3.length()!=s1.length()+s2.length())
return false;
if(s1.length()==)
return s2==s3;
if(s2.length()==)
return s1==s3;
vector<vector<bool> > dp(s1.length()+,vector<bool>(s2.length()+,false));
dp[][] = true;
for(int i=;i<=s1.length();i++)
dp[i][] = dp[i-][]&&(s3[i-]==s1[i-]);
for(int i=;i<=s2.length();i++)
dp[][i] = dp[][i-]&&(s3[i-]==s2[i-]);
for(int i=;i<=s1.length();i++)
{
for(int j=;j<=s2.length();j++)
{
int t = i+j;
if(s1[i-]==s3[t-])
dp[i][j] = dp[i][j]||dp[i-][j];
if(s2[j-]==s3[t-])
dp[i][j] = dp[i][j]||dp[i][j-];
}
}
return dp[s1.length()][s2.length()];
}
};

别人正确的:java

public class Solution {
/**
* Determine whether s3 is formed by interleaving of s1 and s2.
* @param s1, s2, s3: As description.
* @return: true or false.
*/
public boolean isInterleave(String s1, String s2, String s3) {
// write your code here
if(s1.length() + s2.length() != s3.length())
return false;
// if(s1.equals("")&& s2.equals(s3))
// return true;
// if(s2.equals("")&&s1.equals(s3))
// return true;
boolean[][] matched= new boolean[s1.length()+1][s2.length()+1];//在java中布尔型的数组可行;
matched[0][0]= true;
for(int i1=1;i1<= s1.length(); i1++){
if(s3.charAt(i1-1) == s1.charAt(i1-1))
matched[i1][0] = true;
}
for(int i2= 1;i2<= s2.length();i2++){
if(s3.charAt(i2-1) == s2.charAt(i2-1))
matched[0][i2] = true;
}
for(int i1=1;i1<=s1.length(); i1++){
char c1 = s1.charAt(i1-1);
for(int i2 = 1;i2<= s2.length();i2++){
int i3 = i1+ i2;
char c2 = s2.charAt(i2- 1);
char c3 = s3.charAt(i3 -1);
if(c1 == c3)
matched[i1][i2] =matched[i1][i2] || matched[i1-1][i2];
if( c2== c3)
matched[i1][i2] = matched[i1][i2] || matched[i1][i2-1]; }
}
return matched[s1.length()][s2.length()];
}
};

最后更正类型定义后:

class Solution {
public:
/**
* Determine whether s3 is formed by interleaving of s1 and s2.
* @param s1, s2, s3: As description.
* @return: true of false.
*/
bool isInterleave(string s1, string s2, string s3) {
// write your code here
// 先写出最基本的条件; if(s3.length()!=s1.length()+s2.length()){
return false;
} vector<vector<bool> > matched(s1.length()+,vector<bool>(s2.length()+,false));//为何如此定义要清楚!! matched[][]=true;
for(int j=;j<s2.length();j++){
if(s3[j]==s2[j]){
matched[][j+]=matched[][j];
}
}
for(int i=;i<s1.length();i++){
if(s3[i]==s1[i]){
matched[i+][]=matched[i][];
}
} for(int i=;i<s1.length()+;i++){
for(int j=;j<s2.length()+;j++){
if((s3[i+j-]==s1[i-]&&matched[i-][j])||(s3[i+j-]==s2[j-]&&matched[i][j-]))
{
matched[i][j]=true;
} }
}
return matched[s1.length()][s2.length()];
}
};

代码有毒,折腾了一天。= =!

总结:

1)递归能写出比较清晰简单的代码,但是有比较高的时间复杂度;

2)在递归不满足条件的情况下,动态规划是个比较好的选择;

3)一般来说,独立变量的个数决定动态规划的维度,例如l1和l2独立变化,所以用了二维动态规划。

Lintcode--006(交叉字符串)的更多相关文章

  1. lintcode 中等题:interleaving String 交叉字符串

    题目 交叉字符串 给出三个字符串:s1.s2.s3,判断s3是否由s1和s2交叉构成. 样例 比如 s1 = "aabcc" s2 = "dbbca" - 当 ...

  2. LintCode——交叉字符串

    描述:给出三个字符串:s1.s2.s3,判断s3是否由s1和s2交叉构成. 样例:s1 = "aabcc" s2 = "dbbca" - 当 s3 = &quo ...

  3. 交叉字符串 · Interleaving String

    [抄题]: 给出三个字符串:s1.s2.s3,判断s3是否由s1和s2交叉构成.(洗牌) 比如 s1 = "aabcc" s2 = "dbbca" - 当 s3 ...

  4. Lintcode 157. 判断字符串是否没有重复字符

    ------------------------ 因为字符究竟是什么样的无法确定(比如编码之类的),恐怕是没办法假设使用多大空间(位.数组)来标记出现次数的,集合应该可以但感觉会严重拖慢速度... 还 ...

  5. 【LintCode】转换字符串到整数

    问题描述: 实现atoi这个函数,将一个字符串转换为整数.如果没有合法的整数,返回0.如果整数超出了32位整数的范围,返回INT_MAX(2147483647)如果是正整数,或者INT_MIN(-21 ...

  6. lintcode:strStr 字符串查找

    题目: 字符串查找 字符串查找(又称查找子字符串),是字符串操作中一个很有用的函数.你的任务是实现这个函数. 对于一个给定的 source 字符串和一个 target 字符串,你应该在 source ...

  7. LintCode 55 比较字符串

    比较两个字符串A和B,确定A中是否包含B中所有的字符.字符串A和B中的字符都是 大写字母 注意事项 在 A 中出现的 B 字符串里的字符不需要连续或者有序.   样例 给出 A = "ABC ...

  8. 【LintCode·容易】字符串置换

    字符串置换 描述: 给定两个字符串,请设计一个方法来判定其中一个字符串是否为另一个字符串的置换. 置换的意思是,通过改变顺序可以使得两个字符串相等. 样例: "abc" 为 &qu ...

  9. [LintCode]判断一个字符串是否包含另一个字符串的所有字符

    问题描述: 比较两个字符串A和B,确定A中是否包含B中所有的字符.字符串A和B中的字符都是 大写字母. 样例 给出 A = "ABCD" B = "ACD",返 ...

随机推荐

  1. Stack Overflow requires external JavaScript from another domain, which is blocked or failed to load.

    出现以上问题,只是说明stackoverflow前端库用到google的API来,所以stackoverflow躺枪.查阅后,是因为调用jquery的问题. 详情请看: 解决方案有好几种: 1.将ht ...

  2. 找到 OSChina 早上 8 点钟容易宕机的原因 ?

    最近一段时间,OSChina 网站在早上 8 点出头的时候很容易因为数据库连接池爆满而导致网站宕机.表现的情况是数据库处理大量的查询,堆积大量并发连接,导致无法再连接到数据库,执行一个简单的查询速度也 ...

  3. 2015第27周三Java内存模型

    自己写的代码,6个月不看也是别人的代码,自己学的知识也同样如此,学完的知识如果不使用或者不常常回顾,那么还不是自己的知识. 要认识java线程安全,必须了解两个主要的点:java的内存模型,java的 ...

  4. 警惕P2B模式

    大家都知道P2P是什么,估计也有很多人了解P2B的意思,这里也不多做解释,但是为什么要警惕P2B,这里我要做详细说明,希望能给大家一个参考.      首先我们要把P2B分成两种,一种是针对大型企业, ...

  5. mysql-创建函数,存储过程以及视图

    1.创建函数  mysql>delimiter //  mysql>create function 函数名(参数1 参数1类型,...) returns 返回类型       >be ...

  6. 我的eclipse插件推荐

    1. ER图工具 ERMaster - http://ermaster.sourceforge.net/update-site/   优点:可根据数据库生成ER图.支持生成转换成PNG,JavaDOC ...

  7. javascript中子类如何继承父类

    参考阮一峰的文章:http://javascript.ruanyifeng.com/oop/inheritance.html#toc4 function Shape() { this.x = 0; t ...

  8. Lance老师UI系列教程第八课->新浪新闻SlidingMenu界面的实现

    UI系列教程第八课:Lance老师UI系列教程第八课->新浪新闻SlidingMenu界面的实现 今天蓝老师要讲的是关于新浪新闻侧滑界面的实现.先看看原图: 如图所示,这种侧滑效果以另一种方式替 ...

  9. 四、Solr数据源配置(JNDI、DIH)及定时重做索引

    简介 Solr支持很多种创建索引的方式,包括网页,xml以及数据库,因为我这边做的是企业级的搜索,所以用的是数据库建立索引.其实从数据库建立索引,很大程度上取决于原来的数据库设计. 从数据库建立索引, ...

  10. Oracle VM VirtualBox 随系统自动启动虚拟机的方法

    Oracle VM VirtualBox 随系统自动开启虚拟机的方法 @ECHO OFFcd..cd E:cd..cd E:\VirtualBox\start VirtualBox.exe -star ...