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;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章