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一下就明白了

总结:像这种在逐个打坑,打着打着可能之前的某些坑就连起来成为一个大坑的题,记得用并查集去做。

上一篇:1387. 将整数按权重排序


下一篇:[洛谷P6185] [NOI online 提高]T1 序列