题目:交叉字符串
来源:互联网 发布:暴雪降至 知乎 编辑:程序博客网 时间:2024/05/16 12:23
给出三个字符串:s1、s2、s3,判断s3是否由s1和s2交叉构成。您在真实的面试中是否遇到过这个题?
Yes
样例
比如 s1 = "aabcc" s2 = "dbbca"
- 当 s3 = "aadbbcbcac",返回 true.
- 当 s3 = "aadbbbaccc", 返回 false.
挑战
要求时间复杂度为O(n^2)或者更好
标签 Expand
相关题目 Expand
解题思路:
用3个指针分别指向s1,s2,s3。
比如 i 指向 S1 ,j 指向 S2,k 指向 S3。
从k=s0开始去匹配S1,S2。也分别从i=0,j=0,若i,j都匹配则有2种情况用i匹配或者j匹配递归实现,只有一个匹配时,直接匹配后再去匹配剩下的。不匹配返回false。此时空间时间复杂度较大
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(s3.length()!=s2.length()+s1.length()) return false; if(null==s1||0==s1.length()){ if(s2.equals(s3)){ return true; }else{ return false; } } if(null==s2||0==s2.length()){ if(s1.equals(s3)){ return true; }else{ return false; } } int i = 0; int j = 0; for(int k=0;k<s3.length();k++){ boolean s1flag = false; boolean s2flag = false; if(i<s1.length()&&s1.charAt(i)==s3.charAt(k)){ s1flag = true; } if(j<s2.length()&&s2.charAt(j)==s3.charAt(k)){ s2flag = true; } if(!s1flag&&!s2flag){ return false; }else if(s1flag&&s2flag){ return isInterleave(s1.substring(i+1), s2.substring(j), s3.substring(k+1))||isInterleave(s1.substring(i), s2.substring(j+1), s3.substring(k+1)); }else if(s1flag){ i++; }else{ j++; } } return true; }}
动态规划实现,减少重复的计算
为了减少重复计算,就要使用动态规划来记录中间结果。
这里我使用了一个二维数组result[i][j]来表示s1的前i个字符和s2的前j个字符是否能和s3的前i+j个字符匹配。
状态转移方程如下:
result[i,j] = (result[i-1,j] && s1[i] = s3[i+j]) || (result[i,j-1] && s2[j] = s3[i+j]);
其中0≤i≤len(s1) ,0≤j≤len(s2)
这里我使用了一个二维数组result[i][j]来表示s1的前i个字符和s2的前j个字符是否能和s3的前i+j个字符匹配。
状态转移方程如下:
result[i,j] = (result[i-1,j] && s1[i] = s3[i+j]) || (result[i,j-1] && s2[j] = s3[i+j]);
其中0≤i≤len(s1) ,0≤j≤len(s2)
这样算法复杂度就会下降到O(l1*l2)
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(s3.length()!=s2.length()+s1.length()) return false; if(null==s1||0==s1.length()){ if(s2.equals(s3)){ return true; }else{ return false; } } if(null==s2||0==s2.length()){ if(s1.equals(s3)){ return true; }else{ return false; } } char[] c1 = s1.toCharArray(); char[] c2 = s2.toCharArray(); char[] c3 = s3.toCharArray(); boolean a[][] = new boolean[c1.length+1][c2.length+1]; for(int i=0;i<c1.length;i++){ if(c1[i]==c3[i]){ a[i+1][0] = true; }else { break; } } for(int i=0;i<c2.length;i++){ if(c2[i]==c3[i]){ a[0][i+1] = true; }else { break; } } for(int i=1;i<=c1.length;i++){ for(int j=1;j<=c2.length;j++){ char ci = c1[i-1]; char cj = c2[j-1]; char ck = c3[i+j-1]; a[i][j] = (a[i-1][j]&&ci==ck)||(a[i][j-1]&&cj==ck); } } return a[s1.length()][s2.length()]; }}
0 0
- 题目:交叉字符串
- 交叉字符串
- 交叉字符串
- 交叉字符串
- 交叉字符串
- 交叉字符串
- 交叉字符串
- 字符串题目
- 字符串题目
- LintCode-交叉字符串
- 交叉字符串(medium)
- LintCode(M)交叉字符串
- C 交叉存放字符串
- LintCode 29-交叉字符串
- 字符串交叉插入
- LintCode 29 交叉字符串
- 交叉字符串 Java实现
- LintCode 交叉字符串
- Dynamic Rankings(动态区间求第K小模板题:树套树(第二份模板效率更高,见下面截图))
- 题目:二叉树的锯齿形层次遍历
- 转:JSON字符串还原成JS原生值
- 学习《算法导论》第六章 堆排序 总结
- 使用SOCK_RAW构建全网广播包
- 题目:交叉字符串
- Poj.1113 Wall【凸包】 2015/08/29
- 面向对象的优缺点
- 题目:交错正负数
- 关于python文件操作
- ptmalloc,tcmalloc和jemalloc内存分配策略研究
- 请不要再用MongoDB了
- python学习笔记10
- 背包