97. 交错字符串
思路:方法一,动态规划,v[i][j]表示的是s1中前i个字符和s2中前j个字符交错是否可以组合成s3中前i+j个字符。当s1的第i个字符和s3的第i+j个字符相等,那么v[i][j]的状态就由v[i-1][j]的状态决定;同理,当s2的第j个字符和s3的第i+j个字符相等,那么v[i][j]的状态就由v[i][j-1]的状态决定。
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
int n=s1.size(),m=s2.size(),t=s3.size();
if(n+m!=t) return false;//注意字符长度不等的时候
vector<vector<bool>> v(n+1,vector<bool>(m+1,false));
v[0][0]=1;
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
//这里i和j表示的是前多少字符,所以一定需要大于0,才能访问字符串s1[i-1]和s2[j-1]
if(i>0) v[i][j] =v[i][j] | (v[i-1][j]&&s1[i-1]==s3[i+j-1]);
if(j>0) v[i][j] =v[i][j] | (v[i][j-1]&&s2[j-1]==s3[i+j-1]);
}
}
return v[n][m];
}
};
思路:方法二,动态规划+滚动数组,观察方法一可以发现,进行状态转移时,只用到了数组的第i层和第i-1层,也就是当前层和上一层。我们可以用一维素组来替代二维数组。
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
int n=s1.size(),m=s2.size(),t=s3.size();
if(n+m!=t) return false;
vector<bool> v(m+1,false);
v[0]=1;
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
if(i>0) v[j] =(v[j]&&s1[i-1]==s3[i+j-1]);//注意这里不能在左边加v[j]|,不然影响(v[j]&&s1[i-1]==s3[i+j-1])这一块的处理。
if(j>0) v[j] =v[j] | (v[j-1]&&s2[j-1]==s3[i+j-1]);
}
}
return v[m];
}
};