详细见:leetcode.com/problems/interleaving-string
Java Solution: github
package leetcode;
/*
* 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 P097_InterleavingString {
/*
* 已有的测试数据都通过,提交TLE
*/
static class Solution {
int count = 0;
public boolean isInterleave(String s1, String s2, String s3) {
if (s3 == null) {
return null == s2 && s1 == null;
}
if (s1 == null || s1.length() == 0) {
return s3.equals(s2);
} else if (s2 == null || s2.length() == 0) {
return s3.equals(s1);
}
if (s1.length() + s2.length() != s3.length()) {
return false;
}
boolean ans = solve(s1.toCharArray(), 0, s2.toCharArray(), 0, s3.toCharArray(), 0);
System.out.println(count);
return ans;
}
private boolean solve(char[] ch1, int i1, char[] ch2, int i2, char[] ch3, int i3) {
count ++;
if (i1 == ch1.length && i3 < ch3.length) {
return solve(ch2, i2, ch3, i3);
} else if (i2 == ch2.length && i3 < ch3.length) {
return solve(ch1, i1, ch3, i3);
} else if (i3 == ch3.length) {
return i1 == ch1.length && i2 == ch2.length;
}
if (ch1[i1] == ch2[i2]) {
if (ch1[i1] != ch3[i3]) {
return false;
} else {
return solve(ch1, i1 + 1, ch2, i2, ch3, i3 + 1) ||
solve(ch1, i1, ch2, i2 + 1, ch3, i3 + 1);
}
}
if (ch1[i1] == ch3[i3]) {
return solve(ch1, i1 + 1, ch2, i2, ch3, i3 + 1);
}
if (ch2[i2] == ch3[i3]) {
return solve(ch1, i1, ch2, i2 + 1, ch3, i3 + 1);
}
return false;
}
private boolean solve(char[] ch1, int i1, char[] ch2, int i2) {
int j1 = i1, j2 = i2;
while (j1 < ch1.length && j2 < ch2.length) {
if (ch1[j1 ++] != ch2[j2 ++]) {
return false;
}
}
return j1 == ch1.length && j2 == ch2.length;
}
}
/*
* 对于这类问题,肯定要尝试DP
* 12 ms
*/
static class Solution2 {
public boolean isInterleave(String s1, String s2, String s3) {
if (s3 == null) {
return null == s2 && s1 == null;
}
if (s1 == null || s1.length() == 0) {
return s3.equals(s2);
} else if (s2 == null || s2.length() == 0) {
return s3.equals(s1);
}
int m = s1.length(), n = s2.length();
if (m + n != s3.length()) {
return false;
}
boolean[][] path = new boolean[m + 1][n + 1];
path[0][0] = true;
for (int i = 1; i < m + 1; i ++) {
path[i][0] = path[i - 1][0] & (s1.charAt(i - 1) == s3.charAt(i - 1));
}
for (int j = 1; j < n + 1; j ++) {
path[0][j] = path[0][j - 1] & (s2.charAt(j - 1) == s3.charAt(j - 1));
}
for (int i = 1; i < m + 1; i ++) {
for (int j = 1; j < n + 1; j ++) {
path[i][j] = (path[i - 1][j] & (s1.charAt(i - 1) == s3.charAt(i + j - 1))) ||
(path[i][j - 1] & (s2.charAt(j - 1) == s3.charAt(i + j - 1)));
}
}
return path[m][n];
}
}
}
C Solution: github
/*
url: leetcode.com/problems/interleaving-string
recur: TLE
dp/dp2: AC 3ms 42.86%
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define bool int
bool cmp_str(char* s1, int i1, int n1, char* s2, int i2, int n2) {
if (n1-i1 != n2-i2) return 0;
while (i1 < n1) {
if (s1[i1] != s2[i2]) return 0;
i1 ++;
i2 ++;
}
return 1;
}
bool search(char* s1, int i1, int n1, char* s2, int i2, int n2, char* s3, int i3, int n3) {
if (i1 == n1) return cmp_str(s2, i2, n2, s3, i3, n3);
if (i2 == n2) return cmp_str(s1, i1, n1, s3, i3, n3);
if (s1[i1] == s3[i3] && search(s1, i1+1, n1, s2, i2, n2, s3, i3+1, n3))
return 1;
if (s2[i2] == s3[i3] && search(s1, i1, n1, s2, i2+1, n2, s3, i3+1, n3))
return 1;
return 0;
}
bool isInterleave_recur(char* s1, char* s2, char* s3) {
int n1 = s1 == NULL ? 0 : strlen(s1);
int n2 = s2 == NULL ? 0 : strlen(s2);
int n3 = s3 == NULL ? 0 : strlen(s3);
if (n1+n2 != n3) return 0;
return search(s1, 0, n1, s2, 0, n2, s3, 0, n3);
}
bool isInterleave_dp(char* s1, char* s2, char* s3) {
int n1 = s1 == NULL ? 0 : strlen(s1);
int n2 = s2 == NULL ? 0 : strlen(s2);
int n3 = s3 == NULL ? 0 : strlen(s3);
int i1 = 0, i2 = 0, ans = 0;
char** m = NULL;
if (n1+n2 != n3) return 0;
m = (char**) malloc(sizeof(char*) * (n1+1));
for (i1 = 0; i1 <= n1; i1 ++) {
m[i1] = (char*) malloc(sizeof(char) * (n2 + 1));
memset(m[i1], '0', n2+1);
}
m[0][0] = '1';
for (i1 = 1; i1 <= n1; i1 ++) {
if (s1[i1-1] != s3[i1-1]) break;
m[i1][0] = '1';
}
for (i2 = 1; i2 <= n2; i2 ++) {
if (s2[i2-1] != s3[i2-1]) break;
m[0][i2] = '1';
}
for (i1 = 1; i1 <= n1; i1 ++) {
for (i2 = 1; i2 <= n2; i2 ++) {
if (s1[i1-1] == s3[i1+i2-1]) {
if (m[i1-1][i2] == '1')
m[i1][i2] = '1';
}
if (s2[i2-1] == s3[i1+i2-1]) {
if (m[i1][i2-1] == '1')
m[i1][i2] = '1';
}
}
}
ans = m[n1][n2] == '1';
for (i1 = 0; i1 <= n1; i1 ++) free(m[i1]);
return ans;
}
bool isInterleave_dp2(char* s1, char* s2, char* s3) {
int n1 = s1 == NULL ? 0 : strlen(s1);
int n2 = s2 == NULL ? 0 : strlen(s2);
int n3 = s3 == NULL ? 0 : strlen(s3);
int i1 = 0, i2 = 0, ans = 0;
char* m = NULL;
if (n1+n2 != n3) return 0;
m = (char*) malloc(sizeof(char) * (n2 + 2));
memset(m, '0', n2+2);
m[n2+1] = '\0';
m[0] = '1';
for (i2 = 1; i2 <= n2; i2 ++) {
if (s2[i2-1] != s3[i2-1]) break;
m[i2] = '1';
}
for (i1 = 1; i1 <= n1; i1 ++) {
if (m[0] == '1' && s1[i1-1] != s3[i1-1])
m[0] = '0';
for (i2 = 1; i2 <= n2; i2 ++) {
if (s2[i2-1] == s3[i1+i2-1] && m[i2-1] == '1') {
m[i2] = '1';
} else if (s1[i1-1] == s3[i1+i2-1] && m[i2] == '1') {
m[i2] = '1';
} else m[i2] = '0';
}
}
ans = m[n2] == '1';
free(m);
return ans;
}
bool isInterleave(char* s1, char* s2, char* s3) {
return isInterleave_dp2(s1, s2, s3);
}
int main() {
char* s1 = "aacaac";
char* s2 = "aacaaeaac";
char* s3 = "aacaaeaaeaacaac";
printf("answer is %d\r\n", isInterleave_dp(s1, s2, s3));
printf("answer is %d\r\n", isInterleave_recur(s1, s2, s3));
printf("answer is %d\r\n", isInterleave_dp2(s1, s2, s3));
return 0;
}
Python Solution: github
#coding=utf-8
'''
url: leetcode.com/problems/interleaving-string
@author: zxwtry
@email: zxwtry@qq.com
@date: 2017年4月25日
@details: Solution: 92ms 18.64%
'''
class Solution(object):
def isInterleave(self, s1, s2, s3):
"""
:type s1: str
:type s2: str
:type s3: str
:rtype: bool
"""
n1 = 0 if s1 == None else len(s1)
n2 = 0 if s2 == None else len(s2)
n3 = 0 if s3 == None else len(s3)
if n1+n2 != n3: return False
dp = [[False for j in range(n2+1)] for i in range(n1+1)]
dp[0][0] = True
for j in range(1, n2+1):
if n2[j-1] != s3[j-1]: break
dp[0][j] = True
for i in range(1, n1+1):
if n1[i-1] != s3[i-1]: break
dp[i][0] = True
for i in range(1, n1+1):
for j in range(1, n2+1):
if s1[i-1] == s3[i+j-1] and dp[i-1][j]:
dp[i][j] = True
if s2[j-1] == s3[i+j-1] and dp[i][j-1]:
dp[i][j] = True
return dp[n1][n2]