Dinamic Programming
题目描述:
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.
解题思路:
因为整个字符串能否被合成与其中的部分能否被合成有关,考虑使用canForm数组标记使用一定长度的s1和s2能否构成s3的其中一部分。
用canForm[i][j] == true表示s1的前i个字符和s2的前j个字符可以重排成s3的前i+j个字符,false则不能。状态转移方程为
canForm[j][i-j] = (canForm[j-1][i-j] && s1[j-1] == s3[i-1]) || (canForm[j][i-j-1] && s2[i-j-1] == s3[i-1]);
最终canForm[s1.length()][s2.length()]的值表示了整个s3是否能被合成。
实现时需要注意数组边界的处理。
代码实现:
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
vector< vector<bool> > canForm;
canForm.reserve(s1.length()+1);
int i, j;
int l1 = s1.length(), l2 = s2.length();
if (l1 + l2 != s3.length()) return false;
vector<bool> tmp;
tmp.reserve(s2.length()+1);
for (i = 0; i <= l2; i++) {
tmp.push_back(false);
}
for (i = 0; i <= l1; i++) {
canForm.push_back(tmp);
}
canForm[0][0] = true;
for (i = 1; i <= s3.length(); i++) {
if (i <= l2)
canForm[0][i] = canForm[0][i-1] && s2[i-1] == s3[i-1];
if (i <= l1)
canForm[i][0] = canForm[i-1][0] && s1[i-1] == s3[i-1];
for (j = 1; j < i && j <= l1; j++) {
if (i - j <= l2) canForm[j][i-j] = (canForm[j-1][i-j] && s1[j-1] == s3[i-1]) || (canForm[j][i-j-1] && s2[i-j-1] == s3[i-1]);
}
}
return canForm[l1][l2];
}
};
101 / 101 test cases passed.
Status: Accepted
Runtime: 3 ms
Your runtime beats 14.20 % of cpp submissions.
运行时间与大多数提交相近。