LeetCode 721. 賬戶合併 (並查集、字符串處理、善用STL)

賬戶合併

這題仍然就是並查集的基本操作,難點在於建模困難,怎麼將這個賬戶、郵箱合併的問題轉換爲最原始的並查集問題。

如何建模:
① 將username進行1~n的編號,username纔是我們並查集要處理的元素對象,而不是郵箱。
② 利用map<string,int>將每一個郵箱地址字符串映射到它的用戶名,也就是上面的1~n。
③ 如果郵箱字符串發生了重複,將當前郵箱的用戶i和與它重複的字符串的用戶j 進行並查集的合併操作。
④ 最終,一共有多少個不同的並查集,就有多少個不同的用戶。遍歷1~n,利用map<int,vector<int>>來存儲一個代表元有多少個用戶名(當然,實際上都是他自己)。
⑤ 根據map<int<vector<int>>得出答案,中間用set<string>存儲郵箱,爲了去重排序

struct UFS{
    int f[1010];
    UFS(){
        for(int i=0;i<1010;i++){
            f[i] = i;
        }
    }
    int find(int x){
        return x==f[x]?x:f[x]=find(f[x]);
    }
    void merge(int x,int y){
        f[find(x)] = find(y);
    }
};

class Solution {
public:
    vector<vector<string>> accountsMerge(vector<vector<string>>& accounts) {
        map<string,int> mailID;
        UFS ufs;

        for(int i=0;i<accounts.size();i++){
            for(int j=1;j<accounts[i].size();j++){
                if(mailID.count(accounts[i][j])){
                    int id = mailID[accounts[i][j]];
                    ufs.merge(id,i);
                }else{
                    mailID[accounts[i][j]] = i;
                }
            }
        }
        map<int,vector<int>> res;
        for(int i=0;i<accounts.size();i++){
            int fa = ufs.find(i);
            // cout<<i<<"  "<<fa<<endl;
            if(!res.count(fa)){
                res[fa] = vector<int>{i}; 
            }else{
                res[fa].push_back(i);
            }
        }
        cout<<res.size()<<endl;
        vector<vector<string>> ans;
        map<int,vector<int>>::iterator it  = res.begin();
        for(;it!=res.end();it++){
            vector<string> v;
            set<string> s;
            v.push_back(accounts[it->first][0]);
            for(int i:it->second){
                for(int j=1;j<accounts[i].size();j++){
                    s.insert(accounts[i][j]);
                }
            }
            for(set<string>::iterator itt = s.begin();itt!=s.end();itt++){
                v.push_back(*itt);
            }
            ans.push_back(v);
        }
        return ans;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章