Я решил его с помощью синтаксического дерева + дп.
Сначала вставьте свои подстроки в три.Затем определите состояние dp - это некоторая строка, пройдите через эту строку и рассмотрите каждую i (для i = 0 .. s.length()) как начало некоторой подстроки. пусть j = i и increment j, если у вас есть суффикс в trie (который определенно приземляет вас по крайней мере на одну подстроку и может быть больше, если у вас есть общий суффикс между некоторой подстрокой, например «abce» и «abdd»,), всякий раз, когда вы сталкиваетесь с завершением некоторой подстроки, переходите к решению новой подзадачи и найдите минимум между всеми сокращениями подстроки.
Вот мой код для этого. Не беспокойтесь о длине кода. Просто прочитайте функцию решения и забудьте о пути, я включил его для печати созданной строки.
struct node{
node* c[26];
bool str_end;
node(){
for(int i= 0;i<26;i++){
c[i]=NULL;
}
str_end= false;
}
};
class Trie{
public:
node* root;
Trie(){
root = new node();
}
~Trie(){
delete root;
}
};
class Solution{
public:
typedef pair<int,int>ii;
string get_str(string& s,map<string,ii>&path){
if(!path.count(s)){
return s;
}
int i= path[s].first;
int j= path[s].second;
string new_str =(s.substr(0,i)+s.substr(j+1));
return get_str(new_str,path);
}
int solve(string& s,Trie* &t, map<string,int>&dp,map<string,ii>&path){
if(dp.count(s)){
return dp[s];
}
int mn= (int)s.length();
for(int i =0;i<s.length();i++){
string left = s.substr(0,i);
node* cur = t->root->c[s[i]-97];
int j=i;
while(j<s.length()&&cur!=NULL){
if(cur->str_end){
string new_str =left+s.substr(j+1);
int ret= solve(new_str,t,dp,path);
if(ret<mn){
path[s]={i,j};
}
}
cur = cur->c[s[++j]-97];
}
}
return dp[s]=mn;
}
string removeSubstrings(vector<string>& substrs, string s){
map<string,ii>path;
map<string,int>dp;
Trie*t = new Trie();
for(int i =0;i<substrs.size();i++){
node* cur = t->root;
for(int j=0;j<substrs[i].length();j++){
if(cur->c[substrs[i][j]-97]==NULL){
cur->c[substrs[i][j]-97]= new node();
}
cur = cur->c[substrs[i][j]-97];
if(j==substrs[i].length()-1){
cur->str_end= true;
}
}
}
solve(s,t,dp,path);
return get_str(s, path);
}
};
int main(){
vector<string>substrs;
substrs.push_back("ab");
substrs.push_back("cd");
Solution s;
cout << s.removeSubstrings(substrs,"ccdaabcdbb")<<endl;
return 0;
}
Какова масштабная проблема (длина строки, число 'n' подстрок)? BFS решит его, но может быть недостаточно эффективным для больших строк. – amit
@amit Я предполагаю, что BFS возьмет O (| S |^2 * | SET |) – piotrekg2