作者:disappearedgod
时间:2014-6-13
题目
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.
解法
一个有问题的想法
public class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
int i = 0 , j = 0 , k = 0;
char c1 , c2 , c3 ;
int len1 = s1.length(), len2 = s2.length(), len3 = s3.length();
if(len3 == 0)
return len1 == 0 && len2 == 0;
while((i<len1 || j<len2) && k < len3){
c3 = s3.charAt(k);
if(len1>i){
c1 = s1.charAt(i);
if(c3 == c1){
i++;
k++;
continue;
}
else
break;
}
if(len2>j){
c2 = s2.charAt(j);
if (c3 == c2){
j++;
k++;
continue;
}
else
break;
}
break;
}
return i ==len1 && j==len2 && k == len3;
}
}
结果
Input: | "aa", "ab", "aaba" |
Output: | false |
Expected: | true |
递归想法
代码
public class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
if(s3==null)
return s1==null && s2==null;
int len1 = 0, len2 = 0, len3 = 0;
if(s1!=null)
len1 = s1.length();
if(s2!=null)
len2 = s2.length();
len3 = s3.length();
if(len3!=len1+len2)
return false;
if( len1 == 0)
return s2.equals(s3);
if( len2 == 0)
return s1.equals(s3);
len1--;len2--;len3--;
if(s1.charAt(0)==s3.charAt(0) && s2.charAt(0)==s3.charAt(0)){
if(len1 > 0 && len2 > 0 && len3 > 0)
return isInterleave(s1.substring(1,len1),s2,s3.substring(1,len3)) || isInterleave(s1,s2.substring(1,len2),s3.substring(1,len3));
else if(len1 > 0 && len3 > 0)// len2++ == 1
return isInterleave(s1.substring(1,len1),null,s3.substring(1,len3)) || isInterleave(s1.substring(1,len1),s2,s3.substring(1,len3));
else if(len2 > 0 && len3 > 0)//len1++ == 1
return isInterleave(null,s2,s3.substring(1,len3)) || isInterleave(s1,s2.substring(1,len2),s3.substring(1,len3));
else
return false;
}
else if(s1.charAt(0)==s3.charAt(0)){
if(len1 > 0 && len3 > 0)
return isInterleave(s1.substring(1,len1),s2,s3.substring(1,len3));
else if(len3 > 0)
return isInterleave(null,s2,s3.substring(1,len3));
else
return len2 == 0;
}
else if(s2.charAt(0)==s3.charAt(0)){
if(len2 > 0 && len3 > 0)
return isInterleave(s1,s2.substring(1,len2),s3.substring(1,len3));
else if (len3 > 0)
return isInterleave(s1,null,s3.substring(1,len3));
else
return len1 == 0;
}
else{
return false;
}
}
}
结果
Last executed input:"bbbbbabbbbabaababaaaabbababbaaabbabbaaabaaaaababbbababbbbbabbbbababbabaabababbbaabababababbbaaababaa", "babaaaabbababbbabbbbaabaabbaabbbbaabaaabaababaaaabaaabbaaabaaaabaabaabbbbbbbbbbbabaaabbababbabbabaab", "babbbabbbaaabbababbbbababaabbabaabaaabbbbabbbaaabbbaaaaabbbbaabbaaabababbaaaaaabababbababaababbababbbababbbbaaaabaabbabbaaaaabbabbaaaabbbaabaaabaababaababbaaabbbbbabbbbaabbabaabbbbabaaabbababbabbabbab"
非递归思路
栈储存的思路
每次遇到s1,s2被指针指向的位置时候,储存相同的点。为了回退。(其实是递归的一种非递归实现,还是超时)
public class Solution {
class Node{
int x;
int y;
boolean isPop = false;
Node(int i, int j, boolean bool){
x = i;
y = j;
isPop = bool;
}
}
public boolean isInterleave(String s1, String s2, String s3) {
if(s3==null)
return s1==null && s2==null;
int len1 = 0, len2 = 0, len3 = 0;
if(s1 != null)
len1 = s1.length();
if(s2 != null)
len2 = s2.length();
len3 = s3.length();
if(len3 != len1+len2)
return false;
if( len1 == 0)
return s2.equals(s3);
if( len2 == 0)
return s1.equals(s3);
Queue<Node> q = new LinkedList<Node>();
q.offer(new Node(0, 0, false));
int i = 0, j = 0;
while(!q.isEmpty()){
Node node = q.poll();
i = node.x;
j = node.y;
boolean isPop = node.isPop;
char c1, c2, c3;
while(i + j < len3){
if(i < len1)
c1 = s1.charAt(i);
else
c1 = '.';
if(j < len2)
c2 = s2.charAt(j);
else
c2 = '.';
c3 = s3.charAt(i+j);
if(c1 == c3 && c2 == c3){
if(!isPop){
q.offer(new Node(i, j, true));
i++;
}
else{
j++;
isPop = false;
}
}
else if(c1 == c3){
i++;
if( i > len1)
return false;
}
else if(c2 == c3){
j++;
if(j > len2)
return false;
}
else{
break;
}
}
}
return i + j == len3;
}
}
结果
Submission Result: Time Limit Exceeded
Last executed input: | "cbcccbabbccbbcccbbbcabbbabcababbbbbbaccaccbabbaacbaabbbc", "abcbbcaababccacbaaaccbabaabbaaabcbababbcccbbabbbcbbb", "abcbcccbacbbbbccbcbcacacbbbbacabbbabbcacbcaabcbaaacbcbbbabbbaacacbbaaaabccbcbaabbbaaabbcccbcbabababbbcbbbcbb" |
DP解法
想法
0 c a b ccabcac
0 1 0 0 0
c 1 1 1 1
c 0 0 0 1
a 0 0 0 1
c 0 0 0 1
0 c a b ccabcac
0 1 ? 0 0
c ? 0 0 0
c 0 0 0 0
a 0 0 0 0
c 0 0 0 0
0 c a b ccabcac
0 1 0 0 0
c 1 1 1 1
c 1-* 0 0 1
a 1-* 0 0 1
c 0 0 0 1
0 1 0 0 0
c 1 1 1 1
c 0 0 0 1
a 0 0 0 1
c 0 0 0 1
0 c a b ccabcac
0 1 ? 0 0
c ? 0 0 0
c 0 0 0 0
a 0 0 0 0
c 0 0 0 0
0 c a b ccabcac
0 1 0 0 0
c 1 1 1 1
c 1-* 0 0 1
a 1-* 0 0 1
c 0 0 0 1
0 c a b ccabcac
0 1 1 0 0
c 1 1 1 1
c 1 0 0 1
a 1 0 0 1
c 0 0 0 1
0 1 1 0 0
c 1 1 1 1
c 1 0 0 1
a 1 0 0 1
c 0 0 0 1
代码
public class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
int l1 = s1.length();
int l2 = s2.length();
int l3 = s3.length();
if(l1 != l3 -l2)
return false;
boolean [][] dp = new boolean[l1 + 1][l2 + 1];
dp[0][0] = false;
for(int k = 0; k < l3; k++){
for(int i = 0; i < l3 && i < l1; i++){
int j = k - i;
if(j >= l2)
continue;
dp[i + 1][j + 1] = false;
if(s1.charAt(i) == s3.charAt(k) && dp[i][j + 1])
dp[i + 1][j + 1] = true;
if(s2.charAt(j) == s3.charAt(k) && dp[i + 1][j])
dp[i + 1][j + 1] = true;
}
}
return dp[l1][l2];
}
}
结果
数组越界
改正
递推关系应该是由前面推向后面,所以要做到正好。
代码
public class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
int l1 = s1.length();
int l2 = s2.length();
int l3 = s3.length();
if(l1 != l3 -l2)
return false;
boolean [][] dp = new boolean[l1 + 1][l2 + 1];
dp[0][0] = true;
for(int k = 1; k <= l3; k++){
for(int i = 0; i <= k && i <= l1; i++){
int j = k - i;
if(j > l2)
continue;
dp[i][j] = false;
if(i>0 && s1.charAt(i-1) == s3.charAt(k-1) && dp[i-1][j])
dp[i][j] = true;
if(j > 0 && s2.charAt(j-1) == s3.charAt(k-1) && dp[i][j-1])
dp[i][j] = true;
}
}
return dp[l1][l2];
}
}
结果
Submit Time | Status | Run Time | Language |
---|---|---|---|
3 minutes ago | Accepted | 444 ms | java |