版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/l718531794/article/details/85065194
题目地址:https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/
思路:这题解法不优雅,几乎是卡着过去的,跑了136ms。思路KMP得到出现的所有的位置,然后划框统计区域内出现的单词数量,不加剪枝200ms左右,加上一些剪枝,就能跑进150ms了。
AC代码:
class Solution {
public:
int Next[1005][1005];
void getNext(string s2,int k){
int i,j;
int len2 = s2.length();
Next[k][0] = j =-1;
i = 0;
while(i<len2){
while(j!=-1 && s2[i]!=s2[j])
j = Next[k][j];
Next[k][++i] = ++j;
}
}
vector<int> kmp(string s1,string s2,int k){
vector<int>pos;
int len1 = s1.length();
int len2 = s2.length();
int i,j;
i = j = 0;
while(i<len1){
while(j!=-1 && s1[i]!=s2[j])
j = Next[k][j];
i++;
j++;
if(j == len2){
pos.push_back(i-j);
j = Next[k][j];
}
}
return pos;
}
vector<int> findSubstring(string s, vector<string>& words) {
map<string,int>w;
set<int>x[1005];
int n = words.size();
vector<int>ans;
cout<<s.size()<<endl;
if(n==0 || s.length() == 0)
return ans;
int length = words[0].length();
vector<vector<int> >pos;
int res = 0;
for(int i=0;i<n;i++){
if(!w.count(words[i])){
getNext(words[i],i);
pos.push_back(kmp(s,words[i],i));
w[words[i]] = i;
res++;
}else{
x[w[words[i]]].insert(i);
}
}
//cout<<res<<endl;
int flag[10005];
memset(flag,0x3f3f3f3f,sizeof(flag));
for(int i=0;i<n;i++){
if(w[words[i]]!=i)
continue;
int n_pos = pos[i].size();
for(int j=0;j<n_pos;j++){
flag[pos[i][j]] = i;
}
}
int len = s.size();
for(int i =0;i<=len-n*length ;i++){
set<int>temp;
map<int,int>m;
temp.insert(0x3f3f3f3f);
for(int j = i;j<i+n*length;j+=length){
int now = flag[j];
if(now==0x3f3f3f3f)
break;
temp.insert(now);
if(m.count(now)==0)
m[now] = 0;
m[now]++;
if(m[now] > x[now].size()+1)
break;
}
int sum = 0;
set<int>::iterator it;
for(it = temp.begin();it!=temp.end();it++){
if(*it == 0x3f3f3f3f)
continue;
if(x[*it].size()+1 >= m[*it])
sum+=m[*it];
else
break;
}
if(sum == n)
ans.push_back(i);
}
return ans;
}
};