LeetCode 面试题 17.26. 稀疏相似度 (关键就是“稀疏”)

稀疏相似度
最为朴素的做法:
文档之间一一匹配,然后用一个set<int>,记录一下两个文的并集,然后用原来的个数之和减去并集的个数即为交集数。
时间复杂度:
O(n2len)O(n^2*len)

class Solution {
public:
    vector<string> ans;
    vector<string> computeSimilarities(vector<vector<int>>& docs) {
        for(int i=0;i<docs.size();i++){
            for(int j=i+1;j<docs.size();j++){
                unordered_set<int> s;
                for(int x:docs[i]){
                    s.insert(x);
                }
                for(int x:docs[j]){
                    s.insert(x);
                }
                int sum = docs[i].size()+docs[j].size()-s.size();
                if(sum){
                    char res[100];
                    sprintf(res,"%d,%d: %.4f",i,j, 1.0*sum/s.size()+ 1e-9 );
                    ans.push_back(res);
                }
            }
        }
        return ans;
    }
};

如何优化呢?注意到题干的稀疏二字,意思是有大量数字它们从头至尾只出现了一次,但是为了求出交集,我们却不得不把这些只出现了一次的单词也插入到set中。
所以,我们只需预处理一下某个数字在那些文档里出现过,
unordered_map<int,vector<int>> word,记录,然后一个二维数组统计交集。
但要注意,在一般的数据下,这并不能起到优化效果。时间复杂度并没有改变。

class Solution {
public:
    vector<string> computeSimilarities(vector<vector<int>>& docs) {
        vector<string> ans;
        unordered_map<int,vector<int>> word;
        int n = docs.size();
        for(int i=0;i<n;i++){
            for(int x:docs[i]){
                word[x].push_back(i);
            }
        }
        vector<vector<int>> count(n,vector<int>(n,0));
        for(auto it:word){
            vector<int> &ids = it.second;
            for(int i=0;i<ids.size();i++){
                for(int j=i+1;j<ids.size();j++){
                    count[ids[i]][ids[j]]++;
                }
            }
        }
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                if(count[i][j]){
                    int bs = docs[i].size()+docs[j].size()-count[i][j];
                    char buf[100];
                    sprintf(buf,"%d,%d: %.4f",i,j,1.0*count[i][j]/bs + 1e-9);
                    ans.push_back(buf);
                }
            }
        }
        return ans;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章