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.
Typical DP problem:
boolean[][][] dp = new boolean[i][j][k]
We could use dp[i][j][k] to represent if it is interleaving string for s1 start from i, s2 start from j and s3 start from k.
and the ans is dp[0][0][0].
Use the example above dp[1][1][2] means whether "dbbbaccc" can be interleaved by "abcc" and "bbcc"
generally:
if(S1[i] == S3[K])
dp[i][j][k] = dp[i][j][k] || dp[i + 1][j][k + 1]
if(S2[J] == S3[K])
dp[i][j][k] = dp[i][j][k] || dp[i][j + 1][k + 1]
INITIAL STATE dp[s1.length][s2.length][s3.length] = true;
it means "" can be interleaved by "" and ""
Code:
public class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
boolean[][][] dp = new boolean[s3.length() + 1][s1.length() + 1][s2.length() + 1];
boolean[][][] visited = new boolean[s3.length() + 1][s1.length() + 1][s2.length() + 1];
dp[s3.length()][s1.length()][s2.length()] = visited[s3.length()][s1.length()][s2.length()] = true;
return search(dp,visited,s1,s2,s3,0,0,0);
}
boolean search(boolean[][][] dp, boolean[][][] visited,String s1, String s2, String s3, int i, int j, int k){
//System.out.println(j + " " + k + " " + i);
if(visited[i][j][k]) return dp[i][j][k];
//if(i > s3.length() || j > s1.length() || k > s2.length()) return false;
if(s3.length() - i != s1.length() - j + s2.length() - k) return false;
if(j < s1.length() && s3.charAt(i) == s1.charAt(j)){
dp[i][j][k] = dp[i][j][k] || search(dp,visited,s1,s2,s3,i+1,j+1,k);
}
if(k < s2.length() && s3.charAt(i) == s2.charAt(k)){
dp[i][j][k] = dp[i][j][k] || search(dp,visited,s1,s2,s3,i+1,j,k+1);
}
visited[i][j][k] = true;
return dp[i][j][k];
}
}
And actually we do not need k since we know the length of s1[i..end] + s2[j..end] == s3[k..end]
So we only need i j and a 2-dimensional array.
Code:
public class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
if(s3.length() != s1.length() + s2.length()) return false;
boolean[][] dp = new boolean[s1.length() + 1][s2.length() + 1];
boolean[][] visited = new boolean[s1.length() + 1][s2.length() + 1];
dp[s1.length()][s2.length()] = visited[s1.length()][s2.length()] = true;
return search(dp,visited,s1,s2,s3,0,0);
}
boolean search(boolean[][] dp, boolean[][] visited,String s1, String s2, String s3, int i, int j){
if(visited[i][j]) return dp[i][j];
int k = i + j;
if(i < s1.length() && s3.charAt(k) == s1.charAt(i)){
dp[i][j] = dp[i][j] || search(dp,visited,s1,s2,s3,i+1,j);
}
if(j < s2.length() && s3.charAt(k) == s2.charAt(j)){
dp[i][j] = dp[i][j] || search(dp,visited,s1,s2,s3,i,j+1);
}
visited[i][j] = true;
return dp[i][j];
}
}
I use memory search here since it is not easy to build the dp[][] array bottom-up.
本文介绍了一种使用动态规划解决字符串交织问题的方法。该方法通过递归搜索和记忆化技术判断字符串s3是否由s1和s2交织而成,并提供两种不同维度的实现方案。

682

被折叠的 条评论
为什么被折叠?



