Union Find

可以使用「并查集」解决的问题,一般都可以使用「深度优先搜索」和「广度优先搜索」完成。但是「深度优先搜索」和「广度优先搜索」不仅回答了连接问题,还回答了路径问题,时间复杂度高。

重点:

  • 路径压缩

  • 每个操作的复杂度是O(1)

class DisjointSet{
    private:
        vector<int> fa;
        int _find(int x){
            if(fa[x]==x)return x;
            else{
                int t = fa[x];
                fa[x] = _find(t);
                return fa[x];
            }
        };
    public:
        DisjointSet(int size){
            for(int i=0;i<size;i++)fa.push_back(i);
        };
        int _union(int a, int b){
            int fa_a = _find(a);
            int fa_b = _find(b);
            fa[fa_a] = fa_b;
            return fa_b;
        };
        bool same(int a,int b){
            return _find(a) == _find(b);
        };
        bool root(int a){
            return fa[a] == a;
        }
};

399. 除法求值

在并查集的基础上,设计辅助的数组记录信息,灵活运用路经压缩。

959. 由斜杠划分区域

这个题目比较一般,没啥特殊的,将每个块分为四个,然后合并对应的块,最后看并查集的个数。

778. 水位上升的泳池中游泳

这个题目有三种解法

  • 结合二分查找做BFS或DFS遍历 $n^2*logn$

    • 选择不同的高度,然后做遍历,看首尾是否可相连。

  • 并查集

    • 从小到大将点和他的上下左右合并操作,判断起点和终点是否在并查集中。

  • 图的最短路径算法

    • 动态维护从起点到各个定点的最短路径,加上

图算法

1202. 交换字符串中的元素

可以推导出:交换关系可以传递

需要注意:

  • 需要建立并查表的倒排,否则会超时间

947. 移除最多的同行或同列石头

首先需要明确的是:同行同列的都属于一个并查集,然后按照规则每个并查集只会留下一颗石头。

803. 打砖块

Last updated

Was this helpful?