1. 程式人生 > 實用技巧 >leetcode [5497. 查詢大小為 M 的最新分組]

leetcode [5497. 查詢大小為 M 的最新分組]

(https://leetcode-cn.com/problems/find-latest-group-of-size-m/)

剛開始寫的時候沒有想到用並查集去做,於是胡亂分析,像什麼用一些pair去記錄子陣列,放進que裡面不斷去分割....到最後也沒寫出來....

這題可以用並查集去做,對於每一個新變成1的位置i,我們去嘗試能否和i-1,i+1連起來,同時用一個num陣列記錄以根節點為起點連續1的個數,然後稍微在合併的時候加一些程式碼就行了,先看程式碼

const int maxn = 1e5+50;
class Solution {
public:
    int fa[maxn];
    int num[maxn];
    int getf(int x){
        if (fa[x] == x) return x;
        return fa[x] = getf(fa[x]);
    }
    void merge(int x,int y){
        int fx = getf(x);
        int fy = getf(y);
        if (fx != fy){
            fa[fy] = fx;
            num[fx] += num[fy];
        }
    }
    int findLatestStep(vector<int>& arr, int m) {
        int n = arr.size(),mcnt = 0;
        for (int i = 0; i <= n; i++){
            fa[i] = -1;
            num[i] = 0;
        }

        int ans = -1,pos = -1;
        for (int i = 0; i < n; i++){
            int idx = arr[i]-1;
            fa[idx] = idx;
            num[idx] = 1;
            if (idx-1 >= 0 && fa[idx-1] != -1){
                if (num[getf(idx-1)] == m) mcnt--; //**
                merge(idx-1,idx);
            }
            if (idx+1 < n && fa[idx+1] != -1){
                if (num[getf(idx+1)] == m) mcnt--; //**
                merge(idx,idx+1);
            }
            if (num[getf(idx)] == m) mcnt++;
            if (mcnt > 0){
                ans = i+1;
            }
        }

        return ans;
    }
};

其中註釋為*的地方很關鍵,mcnt是指當前這個字串中有m個連續1的子字串的個數,至於為什麼要寫這,可以把這兩句去掉在debug一下就明白了

總結:像這種在逐個打坑,打著打著可能之前的某些坑就連起來成為一個大坑的題,記得用並查集去做。