p839. similar-string-groups

https://leetcode-cn.com/problems/similar-string-groups/
仍然是并查集,对于每一个当前遍历到的字符串,检查其后所有字符串是否和他相似。
 
这里采用从前向后判断而非从后向前判读,具体分析可知这样的比较次数要低于从后向前检查的比较次数。
 

c++代码:

#include <iostream>
#include <vector>
#include <string>
#include <cstring>
using namespace std;

class UFSets{
    private:
    int maxSize;
    int setCount;//连通分量数
    vector<int> parent;

    public:
    UFSets(int size=10):maxSize(size){
        parent=vector<int>(size);
        for(int i=0;i<size;i++){
            parent[i]=-1;
        }
        setCount=size;
    }
    ~UFSets(){
        //delete parent;
    }

    int& operator[](int i){
        return parent[i];
    }

    int Find(int v){
    return parent[v]<0?v:Find(parent[v]);
};//查找v所在并查集的根
    bool Union(int v1,int v2){
    int r1=Find(v1),r2=Find(v2);

    if(r1==r2){//若两个结点在同一个并查集
        return false;
    }
    //不在一个并查集则合并
    if(parent[r1]<=parent[r2]){
        parent[r2]+=parent[r1];
        parent[r1]=r2;
    }
    else{
        parent[r1]+=parent[r2];
        parent[r2]=r1;
    }
    setCount--;
    return true;
};//将并查集r1和并查集r2合并

int size(){
    return setCount;
}

};

bool isSim(const string& s1,const string &s2){
    int size=s1.size();
    int n=0;
    for(int i=0;i<size;i++){
        if(s1[i]!=s2[i]){
            n++;
        }
    }
    if(n<=2){
        return true;
    }
    return false;
}

int numSimilarGroups(vector<string>& strs){
    int size=strs.size();
    if(size==0){
        return 0;
    }
    UFSets set(size);

    for(int i=0;i<size;i++){
        for(int j=i+1;j<size;j++){
            if(isSim(strs[i],strs[j])){
                set.Union(i,j);
            }
        }
    }
    return set.size();
}

vector<string> split(string str,string del){
    vector<string> ans;

    char *s=new char[str.length()+1];
    strcpy(s,str.c_str());

    char *d=new char[del.length()];
    strcpy(d,del.c_str());

    char *p=strtok(s,d);
    while(p){
        ans.push_back(p);
        p=strtok(NULL,d);
    }

    return ans;
}

int main(){
    string s;
    cin>>s;
    vector<string> strs=split(s,",");
    for(auto &s:strs){
        s=s.substr(1,s.size()-1);
    }

    cout<<numSimilarGroups(strs)<<endl;
    return 0;
}

输入格式:

"tars","rats","arts","star"
 

caution

输入处理部分:

  • 自定义的split函数实现对c++ string的分割,
    具体参考
    关于其中的p=strtok(NULL,d);解释参照
  • 使用strcpy时需要头文件<cstring>
  • 直接使用strsub进行string的切片操作[a,b)
posted @ 2021-01-31 18:12  圆圆的圈圈  阅读(110)  评论(0)    收藏  举报