面試題 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;
}
};