識海社群打卡-5

夏尾草發表於2024-11-16

839. 相似字串組 - 力扣(LeetCode)

學習打板並查集

安照oi-wiki的說法來說的話,並查集就是按照其字面意思 ,合併與查詢,並查集在經過修改後可以支援單個元素的刪除、移動;

當然學並查集是因為我發現自己連樹狀陣列都有些理解不了,所以先來看點更簡單的,還是不能一步跨太大,我承認我是廢物,看到勿罵;

按照我對這題目意思的理解就是查詢聯通塊的個數,每種相似的構成一種聯通快,單獨的可作為單獨一個聯通塊;

class Solution {
public:
vector<int> f;

int find(int x){
    while(x != f[x]){
        x = f[x] = f[f[x]];
    }
    return x;
}//板子內容,如果是初始值,直接返回初始值,但此題只會改變fi的值並且不會進行第二遍訪問,所以不要考慮不是的情況
  // int find(int x) {
    //    return f[x] == x ? x : f[x] = find(f[x]);
    //}另外一種寫法

bool check(const string &a,const string &b,int len){
    int num = 0;
    for(int i = 0;i <= len;i++){
        if(a[i] != b[i]){
            num++;
            if(num > 2) return false;
        }
    }
    return true;
}//檢查兩個字串是否相似
    int numSimilarGroups(vector<string>& strs) {
        int n = strs.size();
        int m = strs[0].size();
        f.resize(n);
        for(int i = 0;i < n;i++){
            f[i] = i;
        }//進行初始的賦值
        for(int i= 0;i < n;i++){
            for(int j = i + 1;j < n;j++){
                int fi = find(i),fj = find(j);
                if(fi == fj) continue;//fi == fj表示i和j已經指向了一個連通塊
            if(check(strs[i],strs[j],m)) f[fi] = fj;//將fi和fj指向同一個聯通塊
            }
            
        }
        int ret = 0;
        for(int i = 0;i < n;i++){
            if(f[i] == i) ret++;//fi[i] == i即為聯通塊的個數
        }
        return ret;
    }
};