leetcode 97. Interleaving String (hard)
阿新 • • 發佈:2019-02-15
一道動態規劃的hard級題目,雖然實際上也不算難。
因為上一週做的動態規劃題目的影響,開始的時候也沒有想著去寫狀態轉移方程,考慮直接用遞迴做記憶化搜尋(實際上就是暴力搜尋)
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
return isinter(s1,s2,s3,0,0,0);
}
bool isinter(string s1,string s2,string s3,int x,int y,int z)
{
if( x == s1.size() && y == s2.size() && z == s3.size())
return true;
else if(z == s3.size())
return false;
bool match1 =false,match2 = false;
if(x<s1.size())
{
if(s1[x]==s3[z])
{
match1 = isinter (s1,s2,s3,x+1,y,z+1);
}
}
if(match1)
return true;
if(y<s2.size())
{
if(s2[y]==s3[z])
{
match2 = isinter(s1,s2,s3,x,y+1,z+1);
}
}
return match1||match2;
}
};
果不其然被卡了,題目中存在三位數及更高的資料。不用多項式級別的時間複雜度應該是過不去的。
然後想了一下狀態轉移方程,可以將對於s3是否為s1,s2的插入字串改為判斷s1的前i個字元與s2的前j個字元是否能夠構成等長的s3的字首的問題。
這樣子可以構造一個可行性函式F[i,j]表明構造這個字首的可能性,有,即從s1的上一個字元推導而來或是從s2的上一個字元推導而來。
注意要進行合法性檢測。
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Solution {
public:
int getIndex(int x,int y,int xmax)
{
return y*xmax+x;
}
bool isInterleave(string s1, string s2, string s3) {
vector<int> calculate(26,0);
for(int i = 0;i<s1.size() || i<s2.size() || i<s3.size();i++)
{
if(i<s1.size())
calculate[s1[i]-'a']++;
if(i<s2.size())
calculate[s2[i]-'a']++;
if(i<s3.size())
calculate[s3[i]-'a']--;
}
for(int i = 0;i<26;i++)
{
if(calculate[i]!=0)
return false;
}
vector<bool> possible((s1.size()+1)*(s2.size()+1),false);
possible[0] = true;
for(int i = 1;i<=s1.size();i++)
{
int index = getIndex(i,0,s1.size());
if(s1[i-1]==s3[i-1])
possible[index] = true;
else
break;
}
for(int j = 1;j<=s2.size();j++)
{
int index = getIndex(0,j,s1.size());
if(s2[j-1]==s3[j-1])
possible[index] = true;
else
break;
}
for(int i = 1;i<=s1.size();i++)
{
for(int j = 1;j<=s2.size();j++)
{
int index = getIndex(i,j,s1.size());
if(possible[getIndex(i-1,j,s1.size())] && s1[i-1]==s3[i+j-1])
{
possible[index] = true;
}
else if(possible[getIndex(i,j-1,s1.size())] && s2[j-1] == s3[i+j-1])
{
possible[index] = true;
}
}
}
return possible[getIndex(s1.size(),s2.size(),s1.size())];
}
};
int main(void)
{
Solution s;
cout<<s.isInterleave("","","a")<<endl;
return 0;
}
/*
"bbbbbabbbbabaababaaaabbababbaaabbabbaaabaaaaababbbababbbbbabbbbababbabaabababbbaabababababbbaaababaa"
"babaaaabbababbbabbbbaabaabbaabbbbaabaaabaababaaaabaaabbaaabaaaabaabaabbbbbbbbbbbabaaabbababbabbabaab"
"babbbabbbaaabbababbbbababaabbabaabaaabbbbabbbaaabbbaaaaabbbbaabbaaabababbaaaaaabababbababaababbababbbababbbbaaaabaabbabbaaaaabbabbaaaabbbaabaaabaababaababbaaabbbbbabbbbaabbabaabbbbabaaabbababbabbabbab"
*/