算法-并查集-C

记录算法使用场景和算法实现

使用场景

将问题抽象为算法里的图,并查集算法可以根据结点之前关系连通和判断是否连通。

代码实现

c 复制代码
typedef struct UnionFind {
    // 记录连通分量的个数
    int count;
    int *parent;
    int *size;
    int (*find)(struct UnionFind *, int);
    void (*munion)(struct UnionFind *, int, int);
    bool (*isConnet)(struct UnionFind *, int, int);
} UnionFind;
void UFFree(UnionFind *obj) {
    free(obj->parent);
    free(obj->size);
    free(obj);
    return;
}
int UFFind(UnionFind *obj, int x) {
    while (obj->parent[x] != x) {
        // 路径压缩
        obj->parent[x] = obj->parent[obj->parent[x]];
        x = obj->parent[x];
    }
    return x;
}
void UFUnion(UnionFind *obj, int x, int y) {
    int rootX = UFFind(obj, x);
    int rootY = UFFind(obj, y);
    if(rootX == rootY) return;
    if(obj->size[rootX] > obj->size[rootY]) {
        obj->parent[rootY] = rootX;
        obj->size[rootX] += obj->size[rootY];
    }
    else {
        obj->parent[rootX] = rootY;
        obj->size[rootY] += obj->size[rootX];
    }
    obj->count--;
}
bool IsUFConnet(UnionFind *obj, int x, int y) {
    return UFFind(obj, x) == UFFind(obj, y);
}
UnionFind *UFInit(int n) {
    UnionFind *obj = (UnionFind *)malloc(sizeof(UnionFind));
    obj->count = n;
    obj->parent = (int *)malloc(sizeof(int)*n);
    obj->size = (int *)malloc(sizeof(int)*n);
    for(int i=0; i<n; i++) {
        obj->parent[i] = i;
        obj->size[i] = 1;
    }
    obj->find = UFFind;
    obj->isConnet = IsUFConnet;
    obj->munion = UFUnion;
    return obj;
}

示例

leetcode-130. 被围绕的区域

题目浅析:矩形区域中填充'X'和'O',除矩形四边上为'O'及联通的'O'外,其余区域全变成'X'。

c 复制代码
void solve(char** board, int boardSize, int* boardColSize) {
    int m = boardSize;
    int n = boardColSize[0];
    UnionFind *obj = UFInit(m*n+1);
    for(int i=0; i<m; i++) {
        if(board[i][0] == 'O') {
            obj->munion(obj, m*n, i*n);
        }
        if(board[i][n-1] == 'O') {
            obj->munion(obj, m*n, i*n+n-1);
        }
    }
    for(int j=0; j<n; j++) {
        if(board[0][j] == 'O') {
            obj->munion(obj, m*n, j);
        }
        if(board[m-1][j] == 'O') {
            obj->munion(obj, m*n, (m-1)*n+j);
        }
    }
    int dir[4][2] = {{0,-1}, {0,1}, {1,0}, {-1,0}};
    for(int i=1; i<m-1; i++) {
        for(int j=1; j<n-1; j++) {
            if(board[i][j] == 'O') {
                for(int k=0; k<4; k++) {
                    int ni = i+dir[k][0];
                    int nj = j+dir[k][1];
                    if(board[ni][nj] == 'O') {
                        obj->munion(obj, ni*n+nj, i*n+j);
                    }
                }
            }
        }
    }
    for(int i=1; i<m-1; i++) {
        for(int j=1; j<n-1; j++) {
            if(!obj->isConnet(obj, m*n, i*n+j)) {
                board[i][j] = 'X';
            }  
        }   
    }
    return;
}
相关推荐
青梅味猪大肠6 小时前
【深入浅出C++】为什么虚表指针可以解决菱形继承
开发语言·c++
潘潘的嵌入式日记7 小时前
I²C 从机接收总被覆盖?双缓冲要在 STOP 时交接
c语言·开发语言·单片机
Lhan.zzZ7 小时前
QML 组件库:VS2022 + Qt 静态库方案
开发语言·c++·qt·visual studio
敲代码的嘎仔7 小时前
28届后端开发-海康威视日常实习一面(已OC)
java·开发语言·后端·面试·海康威视·实习·大厂
xx~t8 小时前
嵌入式——Linux软件编程——网络1
linux·c语言·网络·vscode·网络协议
小白羊丨9 小时前
如何诊断 Prompt 模板导致的效果下降?
人工智能·算法·prompt
sakiko_9 小时前
OC基础语法(与Swift对比)-1
开发语言·ios·objective-c·swift
迷迭香yy9 小时前
基金档案数据工程实战从收入分析到持仓穿透的Python解析 IG50免费开源股票数据API接口
开发语言·python
晊晌_h9 小时前
嵌入式从0到精通——线程
java·开发语言·jvm
一木 之林10 小时前
五、C++ 新特性、关键字与编译原理(进阶)(二)
java·开发语言·c++