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. JBOSS尝鲜

    环境搭建:1. jdk-6u16-windows-i586.exe2. jboss-5.1.0.GA-jdk6.zip JDK安装: 安装过程很简单,应该都知道怎么安装软件....安装完JDK后,需要 ...

  2. WebAPI 用户认证防篡改实现HMAC(二)签名验证 AbsBaseAuthenticationAttribute--转

    public class ActionFilter : ActionFilterAttribute      {          public override void OnActionExecu ...

  3. android之针对fragment多次调用onCreateView的问题

    private View rootView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup contain ...

  4. 8.2.1.7 Use of Index Extensions 使用索引扩展

    8.2.1.7 Use of Index Extensions 使用索引扩展 InnoDB 自动扩展每个secondary index 通过添加primary key columns to it,考虑 ...

  5. 获取程序中无需释放的ViewController

    AppDelegate.h @property (strong, nonatomic) UIViewController *viewController; 在需要用的地方 #define appDel ...

  6. HRBUST 1987 逃课的孩子

    Sol:HASH + 二分  字符串处理,很基础的操作. 题意很明确就是找重复的次数统计下,范围比较大1≤n≤10000,1≤m≤10000. #include <cstdio> #inc ...

  7. Android学习【Android内核编译流程和错误笔记】

    博客:http://blog.csdn.net/muyang_ren Ubuntu14.04 LTS(要求是64位长期支持版LTS) Jdk1.8 内核:android4.0 一:jdk 1.解压jd ...

  8. 使用zTree控件制作的表格形式的树形+数据菜单

    測试了一下,兼容ie7以上, chrome opera ff 不使用对方css /*------------------------------------- zTree Style version: ...

  9. javascript中的原型理解总结

    经过几天研究查找资料,对原型终于有点理解了,今天就做下总结,不对之处,希望各位能够提出. 1.每一个Javascript对象(null除外)都和另一个对象相关联,“另一个”对象就是我们今天所要总结的原 ...

  10. [Git] Automatically running tests before commits with ghooks

    Wouldn't it be nice if everyone ran the tests before committing code? With ghooks, you can automatic ...