核心:需要获得两两vector间相同元素的个数
错误:普通的O(m²)遍历所有不同的vector,O(n)的unordered_set<int>一个vector<int>,遍历另一个vector找相同元素的算法效率较低,为O(mmn),超时。
注意:它们的相似度非常“稀疏”,也就是说任选 2 个文档,相似度都很接近 0。
思路:通过unordered_map<int,vector<int>> hm统计同一个文字在哪些不同的vector中出现过,O(m*n)。由于相似度非常“稀疏”,map中的vector<int>的size会非常小。那么可以通过二维数组vector<vevtor<int>> sameMatrix遍历hm(记a=hm.size(),b=hm中最长vector<int>的size()),sameMatrix[i][j]代表第i个vector和第j个vector的相同元素个数,O(a*b*b),b很小,通过。
细节注意:char str[256]可以被push_back进vector<string> ans。
代码:
class Solution {
public:
vector<string> computeSimilarities(vector<vector<int>>& docs) {
vector<string> ans;
unordered_map<int,vector<int>> hm;
int m=docs.size();
if(m<2){
return ans;
}
for(int i=0;i<m;i++){
for(auto num:docs[i]){
hm[num].push_back(i);
}
}
vector<vector<int>> sameMatrix(m,vector<int>(m,0));
for(auto &[k,vec]:hm){
//稀疏的,n会非常小
int n=vec.size();
if(n<2){
continue;
}
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
int idx1=min(vec[i],vec[j]);
int idx2=max(vec[i],vec[j]);
sameMatrix[idx1][idx2]++;
}
}
}
for(int i=0;i<m;i++){
for(int j=i+1;j<m;j++){
if(sameMatrix[i][j]){
char str[256];
sprintf(str,"%d,%d: %.4f",i,j,sameMatrix[i][j]*1.0/(docs[i].size()+docs[j].size()-sameMatrix[i][j])+1e-9);
ans.push_back(str);
}
}
}
return ans;
}
};