leetcode 97. Interleaving String
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.
第一个思路肯定可能就是递归了
class Solution {
public:
int mark = 0;
void dfs(string& s1, string& s2, string& s3, int a, int b, int c) {
if (c == s3.size() && a == s1.size() && b == s2.size()) {
mark = 1;
return;
}
for (int i = c; i < s3.size(); ++i) {
if (s1[a] == s3[c]) {
dfs(s1, s2, s3, a+1, b, c+1);
}
if (s2[b] == s3[c]) {
dfs(s1, s2, s3, a, b+1, c+1);
}
}
}
bool isInterleave(string s1, string s2, string s3) {
dfs(s1, s2, s3, 0, 0, 0);
if (mark) return true;
return false;
}
};
但是这样会超时,时间复杂度最坏将近O(n^3) 所以采用dp的方法,能降到O(n^2)的时间复杂度。那么如何dp呢?其实很简单啦
构造一个匹配矩阵,ForExample
可以想象,向右走代表匹配s1[i]和s3[k]向下走代表匹配s2[j]和s3[k],如果能匹配上就记1,那么如果dp[n][m]为1就代表能匹配上。上图给出了一个匹配路径。
那么转移方程如下:
dp[i][j]=dp[i-1][j]&(s1[i]==s3[i+j-1])|(dp[i][j-1]&(s2[j]==s3[i+j-1])
代码如下:
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
int n = s1.size();
int m = s2.size();
vector<vector<int> > dp(n+1, vector<int>(m+1, 0));
dp[0][0] = 1;
if (s3.size() != n + m) return false;
if (n == 0) {
if (s3 == s2) return true;
return false;
}
if (m == 0) {
if (s1 == s3) return true;
return false;
}
for (int i = 0; i <= n; ++i) {
for (int j = 0; j <= m; ++j) {
if (i == 0 && j == 0) continue;
else if (i == 0) dp[i][j] = dp[i][j-1] & (s2[j-1] == s3[i+j-1]);
else if (j == 0) dp[i][j] = dp[i-1][j] & (s1[i-1] == s3[i+j-1]);
else dp[i][j] = (dp[i][j-1] & (s2[j-1] == s3[i+j-1])) | (dp[i-1][j] & (s1[i-1] == s3[i+j-1]));
}
}
return dp[n][m];
}
};
原文地址:http://www.cnblogs.com/pk28/
与有肝胆人共事,从无字句处读书。
欢迎关注公众号:
欢迎关注公众号: