面试题 17.17. 多次搜索
完整的把字典树实现了一遍,不知道字典树的可以先去做实现Ties(前缀树)这道题
解题思路是,把smalls
数组建成字典树,然后再从big[0],big[1]...
开始query
,一旦搜索到了smalls
中的字符串,就把big[i]
中的push
到相应的ans
数组中。smalls
中的string
映射到vector
的下标有很多种方法,这里直接用map
存下来,后面再传给vector
。
class Trie{
private:
Trie* t[26];
bool end;
public:
Trie(){
end = false;
memset(t, 0, sizeof(t));
}
void insert(string s){
int i;
Trie* root = this;
for(i = 0; i < s.size(); i ++){
if(root->t[s[i]-'a'] != NULL){
root = root->t[s[i]-'a'];
}
else break;
}
while(i < s.size()){
Trie* node = new Trie;
root->t[s[i]-'a'] = node;
root = node;
i ++;
}
root->end = true;
}
// 这里一次query直接把从big[i]开始的所有可能的string直接query出来,
// 为了存下这些检测出来的string,直接返回vector<string>
vector<string> query(string s){
int i;
vector<string> vs;
Trie* root = this;
for(i = 0; i < s.size(); i ++){
if(root->t[s[i]-'a'] != NULL){
root = root->t[s[i]-'a'];
if(root->end){
vs.push_back(s.substr(0, i+1));
}
}
else break;
}
return vs;
}
};
class Solution {
public:
vector<vector<int>> multiSearch(string big, vector<string>& smalls) {
Trie* a = new Trie;
for(int i = 0; i < smalls.size(); i ++){
a->insert(smalls[i]);
}
vector<vector<int>> ans;
map<string, vector<int>> m;
// vector<string> vs;
// vs = a->query(string("is"));
// for(int x = 0; x < vs.size(); x ++)
// cout << vs[x] << endl;
// return ans;
for(int i = 0; i < big.size(); i ++){
// 因为一次query可能不止返回一个string,所以用了数组
vector<string> vs;
vs = a->query(big.substr(i, big.size()-i));
// for(int x = 0; x < vs.size(); x ++)
// cout << vs[x] << endl;
for(int j = 0; j < vs.size(); j ++)
m[vs[j]].push_back(i);
}
for(int i = 0; i < smalls.size(); i ++){
ans.push_back(m[smalls[i]]);
}
return ans;
}
};