https://leetcode.com/problems/substring-with-concatenation-of-all-words/
滑动窗口法。解析看这里:
http://www.2cto.com/kf/201406/311648.html
算法时间复杂度为O(n*k))n是字符串的长度,k是单词的长度
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
map<string,int> wd;
for(int i=0;i<words.size();i++)
wd[ words[i] ] ++;
vector <int> ret;
if( words.size() == 0 ||
words[0].size() > s.size() )return ret;
int sz = words[0].size();
for(int i=0;i<sz;i++) {
int winSt = i, cnt=0;
map <string, int> found;
for(int winEnd = i; winEnd <= s.size()-sz; winEnd += sz ) {
//s.size()-sz because word = s.substr(winEnd, sz);
//也就是最后一个位置winEnd开始放words[0]
string word = s.substr(winEnd, sz);
if(wd.find(word) != wd.end()) {
if(wd[word] > found[word]) {
found[word] ++;
cnt ++;
} else {
string tmp;
while( (tmp=s.substr(winSt, sz)) != word ) {
winSt += sz;
found[tmp] --;
cnt --;
}
winSt += sz;
//here can't because -- and insert word , so you needn't do anything except winSt+=sz
//found[tmp] --;
//cnt --;
}
if(cnt == words.size()) { //从下一个位置开始
ret.push_back(winSt);
found[ s.substr(winSt, sz) ] --;
winSt += sz;
cnt --;
}
} else {
found.clear();
winSt = winEnd + sz;
cnt=0;
}
}
}
return ret;
}
};
int main() {
freopen("l30.txt", "r", stdin);
int n;
string s,in;
while(cin >> n) {
vector<string>svec;
for(int i=0;i<n;i++) {
cin >> in;
svec.push_back(in);
}
cin >> s;
Solution so;
vector<int>ans = so.findSubstring(s, svec);
for(int i=0;i<ans.size();i++) {
cout << ans[i] << ", ";
}
cout << "ans end" << endl;
cout << endl;
}
return 0;
}