相似和
给出n个字符串串
,定义两个字符串
的相似度
为他们的最长公共前缀长度
求
案例
输入:3,["niuniu","niumei","niuneng"]
返回值:10
说明:
"niuniu"与"niumei"的相似度为3
"niuniu"与"niuneng"的相似度为4
"niumei"与"niuneng"的相似度为3
所以相似度的总和为10
方法一 暴力
遍历字符串数组对于第i个字符串需要再遍历i之后的所有字符串与第i字符串进行对比统计.
class Solution {
public:
long long solve(int n, vector<string>& s) {
int ans = 0;
for(int i = 0; i < n; i ++){ // 循环第i个字符串
for(int j = i + 1; j < n; j ++){ // 遍历第i个字符串之后的所有字符串
for(int k = 0; k < min(s[i].size(), s[j].size()); k ++){ //判断字符串相同的位数
if(s[i][k] == s[j][k]) ans ++;
else break;
}
}
}
return ans;
}
}; 时间复杂度: 对于第i个字符串每次需要与i之后的所有字符进行对比
空间复杂度: 使用若干个变量
方法二 字典树
将所有的字符串存入字典树中并对每一个存入的字符位置进行计数,之后遍历字符串数组一一匹配答案,对于第i个字符串找寻时只需要将每次的结点值减取i这个位数(即字符串在数组的第几位)即可,详见如图
class Solution {
public:
int tree[1000010][30], cnt[1000010];
int idx = 0;
int push(string a, int ff, int id){ //字典树
int p = 0, res = 0;
for(int i = 0; i < a.size(); i ++){//将字符存入字符树中
int ss = a[i] - 'a';
if(!tree[p][ss]) tree[p][ss] = ++ idx;
p = tree[p][ss];
if(ff) cnt[p] ++; //对于每一位记录过的值进行次数统计
res += max(cnt[p] - id, 0); //计算当前值对于总体的贡献
}
return res;
}
long long solve(int n, vector<string>& s) {
// write code here
int ans = 0;
for(int i = 0; i < n; i ++) push(s[i], 1, 0);
for(int i = 0; i < n; i ++) {
ans += push(s[i], 0, i + 1);
}
cout <<endl;
return ans;
}
}; 时间复杂度: 存储字符串到字典树与读取的复杂度
空间复杂度: 字典树的节点存储以及字符的访问次数

京公网安备 11010502036488号