Leetcode, InterleavingString
力扣官方题解
设状态 f[i][j],表示 s1[0,i] 和 s2[0,j],匹配 s3[0, i+j]。如果 s1 的最后一个字符等于 s3 的最后一个字符,则 f[i][j]=f[i-1][j];如果 s2 的最后一个字符等于 s3 的最后一个字符,
则 f[i][j]=f[i][j-1]。因此状态转移方程如下:
f[i][j] = (s1[i - 1] == s3 [i + j - 1] && f[i - 1][j])
|| (s2[j - 1] == s3 [i + j - 1] && f[i][j - 1]);
#include <iostream>
#include <string>
#include <vector>
using namespace std;
template<typename Inlt>
bool isInterleave(Inlt first1, Inlt last1, Inlt first2, Inlt last2,
Inlt first3, Inlt last3)
{
if (first3 == last3)
return first1 == last1 && first2 == last2;
return (*first1 == *first3
&& isInterleave(std::next(first1), last1, first2, last2, std::next(first3), last3))
|| (*first2 == *first3
&& isInterleave(first1, last1, std::next(first2), last2, std::next(first3), last3));
}
//递归,会超时,仅用来帮助理解
//vs2017 string end报错
bool solution(string s1, string s2, string s3)
{
if (s3.length() != s1.length() + s2.length())
return false;
return isInterleave(begin(s1), end(s1), begin(s2), end(s2),
begin(s3), end(s3));
}
//二维动规,时间复杂度 O(n^2),空间复杂度 O(n^2)
bool solution1(string s1, string s2, string s3)
{
if (s3.length() != s1.length() + s2.length())
return false;
vector<vector<bool>> vec(s1.length() + 1, vector<bool>(s2.length() + 1, true));
//特例 s2为空
for ( size_t i = 1; i <= s1.length(); ++i )
vec[i][0] = vec[i - 1][0] && s1[i - 1] == s3[i - 1];
//特例 s1为空
for (size_t i = 1; i <= s2.length(); ++i)
vec[0][i] = vec[0][i - 1] && s2[i - 1] == s3[i - 1];
for ( size_t i = 1; i <= s1.length(); ++i )
{
for ( size_t j = 1; j <= s2.length(); ++j )
{
vec[i][j] = (s1[i - 1] == s3[i + j - 1] && vec[i - 1][j]
|| s2[j - 1] == s3[i + j - 1] && vec[i][j - 1]);
}
}
return vec[s1.length()][s2.length()];
}
//二维动规 + 滚动数组,时间复杂度 O(n^2),空间复杂度 O(n)
bool solution2(string s1, string s2, string s3)
{
if (s3.length() != s1.length() + s2.length())
return false;
if (s1.length() < s2.length())
return solution2(s2, s1, s3);
vector<bool> vec(s2.length() + 1, true);
for (size_t i = 1; i < s2.length(); ++i)
vec[i] = s2[i - 1] == s3[i - 1] && vec[i - 1];
for (size_t i = 1; i < s1.length(); ++i)
{
vec[0] = s1[i - 1] == s3[i - 1] && vec[0];
for (size_t j = 1; j <= s2.length(); ++j)
{
vec[j] = (s1[i - 1] == s3[i + j - 1] && vec[j])
|| ( s2[j - 1] == s3[i + j - 1] && vec[j - 1] );
}
}
return vec[s2.length()];
}
int main()
{
{
string s1 = "aabcc", s2 = "dbbca";
string s3 = "aadbbcbcac";
cout << solution2(s1, s2, s3) << endl; //true
}
{
string s1 = "aabcc", s2 = "dbbca";
string s3 = "aadbbbaccc";
cout << solution2(s1, s2, s3) << endl; //false
}
{
string s1 = "", s2 = "";
string s3 = "";
cout << solution2(s1, s2, s3) << endl; //true
}
return 0;
}