NC524 单双难全
题解一:字典树
题解思路: 构建两个字典树,一个用字符串奇数位构建,一个用字符串的全部字符创建一个字典树
图示字典树:
复杂度分析:
时间复杂度: :建树的时间复杂度由字符串长度决定,查找前缀树取决前缀长度。 建树需要遍历s字符串数组中的每个字符串,查找需要遍历t字符串数组中的每个字符串
空间复杂度: 空间复杂度最坏情况下是每个字符串都有26个英文字母
实现如下:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 单双难全
* @param n int整型 字符串s的个数
* @param s string字符串vector n个字符串s
* @param m int整型 字符串t的个数
* @param t string字符串vector m个字符串t
* @return int整型vector
*/
typedef struct tree{
int count;
struct tree* next[27];
tree(int c=0,int en = 0):count(c){memset(next,0,sizeof(next));};
}Tire;
Tire* root_1 = new Tire();//奇数根节点
Tire* root_2 = new Tire();
//单数位构建
void insert_ji(string s){
int len = s.size();
Tire* t = root_1;
for(int i = 0;i<len;i+=2){
if(t->next[s[i]-'a']==NULL) t->next[s[i]-'a'] = new Tire();
t = t->next[s[i]-'a'];
t->count++; //表明该节点所关联的单词
}
}
//整个字符串建立字典树
void insert(string s){
int len = s.size();
Tire* t = root_2;
for(int i = 0;i<len;++i){
if(t->next[s[i]-'a']==NULL) t->next[s[i]-'a'] = new Tire();
t = t->next[s[i]-'a'];
t->count++;
}
}
//在完整字典树中查找
int search(string s){
int len = s.size();
Tire* t = root_2;
for(int i = 0;i<len;++i){
if(t->next[s[i]-'a'] == NULL) return 0;
t = t->next[s[i]-'a'];
}
return t->count;
}
//在查找奇数位构建字典树查找
int search_ji(string s){
int len = s.size();
Tire* t = root_1;
for(int i = 0;i<len;i+=2){
if(t->next[s[i]-'a']==NULL) return 0;
t = t->next[s[i]-'a'];
}
return t->count;
}
vector<int> solve(int n, vector<string>& s, int m, vector<string>& t) {
vector<int> ans;
for(auto it:s) {insert_ji(it); insert(it);}
for(auto it:t) {
if(it.size()!=1)
ans.emplace_back(search_ji(it)-search(it));
else ans.emplace_back(search_ji(it));
}
return ans;
}
};
题解二:暴力
题解思路: 遍历两个字符串数组进行比较,判断是否是单匹配串,同时还需要判断是否是双匹配串
复杂度分析:
时间复杂度:,需要遍历两个字符串数组进行字符串的比较。
空间复杂度:,没有申请额外的空间
实现如下:
class Solution {
public:
vector<int> solve(int n, vector<string>& s, int m, vector<string>& t) {
vector<int> res(m, 0);
for(int i = 0; i < m; i++){//遍历字符串数组t
for(int j = 0; j < n; j++){ //遍历字符串数组s
bool flag = true;
if(t[i].length() > s[j].length())
continue;
else{
for(int k = 0; k < t[i].length(); k++){ //查看是否是单匹配串
if(k % 2 == 0){ //检查奇数是否相同
if(t[i][k] == s[j][k])
continue;
else{
flag = false;
break;
}
}
}
if(flag){ //已经是单匹配串
for(int k = 0; k <t[i].length(); k++){ //检查是否是双匹配
if(k % 2 == 1){
if(t[i][k] == s[j][k])
continue;
else{
flag = false;
break;
}
}
}
if(!flag || t[i].length() == 1) //当是单匹配不是双匹配或者t只有一个数时
res[i]++;
}
}
}
}
return res;
}
};
京公网安备 11010502036488号