【LeetCode每日一题】924. 尽量减少恶意软件的传播(并查集)

文章目录


924. 尽量减少恶意软件的传播

思路:并查集
  1. 构建并查集:首先,代码创建了一个 UnionFind 类来维护节点之间的连通关系。它使用了并查集的数据结构,其中 p 数组存储每个节点的父节点,而 size 数组存储每个节点所在集合的大小。
  2. 遍历图并建立连接关系:接下来,代码遍历了给定的图 graph,并对图中存在连接的节点调用 union 方法,将它们所在的集合合并起来。
  3. 统计感染节点数:然后,代码统计了每个初始感染节点所在集合的感染节点数量,并更新了最小节点的值。
  4. 寻找优化的方案:接着,代码再次遍历了初始感染节点数组 initial,对每个节点进行如下操作:
    • 找到该节点所在集合的根节点。
    • 如果该集合中只有一个初始感染节点,那么比较该集合的大小和最大感染节点数,更新答案为当前节点和最大感染节点数。
  5. 返回结果:最后,代码返回了答案,如果没有找到优化的方案,则返回最小节点。
代码:
java 复制代码
class Solution {
    public int minMalwareSpread(int[][] graph, int[] initial) {
        int n = graph.length;
        UnionFind uf = new UnionFind(n);//用并查集维护节点的连通关系
        for (int i = 0; i < n; i++) {
            for (int j = i+1; j < n; j++) {
                if (graph[i][j] == 1) {//如果存在连接
                    uf.union(i, j);//将节点i和节点j所在的集合合并
                }
            }
        }
        int ans = n;
        int min = n;//最小结点
        int max = 0;//最大感染数
        int[] count = new int[n];
        for (int x : initial) {
            count[uf.find(x)]++;//统计每个初始感染节点所在集合的感染节点数量
            min = Math.min(min, x);//更新最小节点
        }
        for (int x : initial) {
            int root = uf.find(x);
            if (count[root] == 1) {
                int size = uf.size(root);
                if (size > max || (size == max && x < ans)) {
                    // 如果当前集合的大小大于最大感染节点数,或者当前集合的大小等于最大感染节点数但节点值较小
                    ans = x;//更新答案为当前节点
                    max = size;//更新最大感染节点数
                }
            }
        }
        return ans == n ? min : ans;//ans==n说明没找到优化的方案,直接返回最小的结点。
    }
}
class UnionFind {
    //维护节点之间的连通关系
    private final int[] p;//存储父结点
    private final int[] size;//存储每个结点所在集合的大小

    public UnionFind(int n) {
        p = new int[n];
        size = new int[n];
        for (int i = 0; i < n; i++) {
            p[i] = i;//把每个父结点设置为自己
            size[i] = 1;//每个集合的初始大小为1
        }
    }

    public int find(int x) {
        //查找结点所在集合的根节点
        if (p[x] != x) {
            //如果父结点不是自己
            p[x] = find(p[x]);
        }
        return p[x];
    }

    public boolean union(int a, int b) { // 将两个节点所在的集合合并
        int pa = find(a);
        int pb = find(b);
        if (pa == pb) {
            //根节点相同,说明两个结点已经是在一个集合中了。
            return false;
        }
        if (size[pa] > size[pb]) {
            p[pb] = pa;//将集合b连接到集合a上
            size[pa] += size[pb];//更新集合a的大小
        }else {
            p[pa] = pb;
            size[pb] += size[pa];
        }
        return true;
    }

    public int size(int root) {
         获取指定根节点所在集合的大小
        return size[root];
    }
}

点击移步博客主页,欢迎光临~

相关推荐
爱吃生蚝的于勒14 分钟前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
羊小猪~~17 分钟前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
王哈哈^_^42 分钟前
【数据集】【YOLO】【VOC】目标检测数据集,查找数据集,yolo目标检测算法详细实战训练步骤!
人工智能·深度学习·算法·yolo·目标检测·计算机视觉·pyqt
星沁城1 小时前
240. 搜索二维矩阵 II
java·线性代数·算法·leetcode·矩阵
脉牛杂德1 小时前
多项式加法——C语言
数据结构·c++·算法
legend_jz1 小时前
STL--哈希
c++·算法·哈希算法
kingmax542120081 小时前
初三数学,最优解问题
算法
一直学习永不止步1 小时前
LeetCode题练习与总结:赎金信--383
java·数据结构·算法·leetcode·字符串·哈希表·计数
小刘|2 小时前
《Java 实现希尔排序:原理剖析与代码详解》
java·算法·排序算法
jjyangyou2 小时前
物联网核心安全系列——物联网安全需求
物联网·算法·安全·嵌入式·产品经理·硬件·产品设计