给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的。
示例 1:
输入: s1 = “aabcc”, s2 = “dbbca”, s3 = “aadbbcbcac”
输出: true
解题思路
数组含义:dp[i][j]s1的前i个和s2的前j个能否组成字符串s3的前i+j长度的子串
状态转移: dp[i][j]=dp[i][j]||(dp[i-1][j]&&s1.charAt(i-1)==s3.charAt(loc))在(i-1,j)的基础上, 判断新加入的s1的i位置是否匹配s3.
代码
class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
int n=s1.length(),m=s2.length();
if(n+m!=s3.length()) return false;
boolean[][] dp=new boolean[n+1][m+1];
dp[0][0]=true;
for(int i=0;i<=n;i++)
for(int j=0;j<=m;j++)
{
int loc=i+j-1;
if(i>0)
dp[i][j]=dp[i][j]||(dp[i-1][j]&&s1.charAt(i-1)==s3.charAt(loc));
if(j>0)
dp[i][j]=dp[i][j]||(dp[i][j-1]&&s2.charAt(j-1)==s3.charAt(loc));
}
return dp[n][m];
}
}
不一样的动态规划代码
class Solution {
public static boolean isInterleave(String s1, String s2, String s3) {
int n=s1.length(),m=s2.length();
if(n+m!=s3.length()) return false;
int[][] dp=new int[n+1][m+1];
for(int i=1;i<=m;i++)
if(s3.charAt(dp[0][i-1])==s2.charAt(i-1))
dp[0][i]=dp[0][i-1]+1;
else dp[0][i]=dp[0][i-1];
for(int i=1;i<=n;i++)
if(s3.charAt(dp[i-1][0])==s1.charAt(i-1))
dp[i][0]=dp[i-1][0]+1;
else dp[i][0]=dp[i-1][0];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{ if(s3.charAt(dp[i-1][j])==s1.charAt(i-1))
dp[i][j]= Math.max(Math.max(dp[i][j-1],dp[i-1][j]+1),dp[i][j]);
if(s3.charAt(dp[i][j-1])==s2.charAt(j-1))
dp[i][j]= Math.max(Math.max(dp[i-1][j],dp[i][j-1]+1),dp[i][j]);
}
return dp[n][m]==s3.length();
}
}