LeetCode 查并集系列 朋友圈 冗余链接等

2023-05-16

网上有作者已经总结的很好 ,这里转载一下:https://www.jianshu.com/p/b81f6db6beaf

 

什么是并查集

一种数据结构,用来描述集合。

  • (find):某个元素是否属于某个集合
  • (Combine):某个元素和另一个元素属于同一个集合

基本的场景:

假设用10个人,用大小为10的数组来表示,a[0] ~ a[9],数据的内容是下标

这十个人中间有互相认识的,互相认识的需要分成一组
比如 5,6 认识,5和6成为一组,这时a[5]的值变成了6,表示5,6已经是一组了

 

1,2认识,a[1]的值变成了2,这时1,2成为一组

 

2,3认识,因为1,2已经是一组了,将a[1],a[2]的下标改成3。这时1,2,3成为一组

 

1,4认识,这时1,2,3,4成为一组,a[1] = a[2] = a[3] = a[4]=4

 

1,5认识,这时1,2,3,4,5,6成为一组,a[1] = a[2] = a[3] = a[4] = a[5] = a[6] = 6

 

我们用树的结构重新表示下数据的结构


并查集有哪些操作呢

  • unionElements():就是上面描述的朋友组队的过程(合并函数)
  • find(x):我是属于那个队的,find(4)=6,说明4属于6队
  • isConnected(x,y)判断两个人是否是一对,isConnected(2,3)=true,说明2和3是属于同一对

老套路,这时候改上代码look look了:

unionElements 方法:

 

public void unionElements(int firstElement, int secondElement) {
        //找出firstElement所在的集合
        int firstUnion = find(firstElement);
        //找出secondElement所在的集合
        int secondUnion = find(secondElement);

        //如果这两个不是同一个集合,那么合并。
        if (firstUnion != secondUnion) {
            //遍历数组,使原来的firstUnion、secondUnion合并为secondUnion
            for (int i = 0; i < this.size; i++) {
                if (id[i] == firstUnion) {
                    id[i] = secondUnion;
                }
            }
        }
    }

find方法:

 

    private int find(int element) {
        return id[element];
    }

isConnected方法:

 

  public boolean isConnected(int firstElement, int secondElement) {
        return find(firstElement) == find(secondElement);
    }

上面是基本的并查集场景,我们先看看类似的LeetCode题目吧

朋友圈就是典型的交并集问题,求的是一共几个分组。
速度撸出代码瞧一瞧~

 

    int[] p;
    int[][] combines;

    public int findCircleNum(int[][] M) {
        combines = M;
        int length = M.length;
        p = new int[M.length];

        // 构造初始化数组
        for (int i = 0; i < length; i++) {
            p[i] = i;
        }

        // combine函数合并
        for (int i = 0; i < length; i++) {
            for (int j = 0; j < length; j++) {
                unionElements(i, j);
            }
        }

        //统计组数
        int res = 0;
        for (int i = 0; i < M.length; i++) {
            if (p[i] == i) {
                res++;
            }
        }
        return res;
    }

    private void unionElements(int i, int j) {
        if (combines[i][j] == 1) {
            int iP = find(i);
            int jP = find(j);
            //如果i所在的组和j所在的组不一致,合并两个组
            if (iP != jP) {
                for (int k = 0; k < p.length; k++) {
                    if(p[k] == iP) {
                        p[k] = jP;
                    }
                }
            }
        }
    }

    private int find(int i) {
        if (p[i] != i) {
            return find(p[i]);
        }
        return p[i];
    }

这道题不难,题目有点绕=。=,感觉LeetCode100分有20分考的是语文和概念理解。感觉是有了代码才编的题。。内核仍然是并查集,

构成树(全连通,无环)=》p数组的值相等,则构成树
多余边 =》发现p数组的两位是否连通,isConnected登场
“多个答案,返回,最后出现的边” =》说的就是让你遍历完

一顿组合拳,撸出答案

 

public class Solution {
    int[] p;

    public int[] findRehdundantConnection(int[][] edges) {
        int[] result = new int[2];
        // 构造初始化数组
        p = new int[edges.length+1];
        
        for (int i = 1; i < edges.length+1; i++) {
            p[i] = i;
        }
        for (int i = 1; i < edges.length+1; i++) {
            //判断成环
            if (isConnected(edges[i-1][0], edges[i-1][1])) {
                result[0] = edges[i-1][0];
                result[1] = edges[i-1][1];
            }
            unionElements(edges[i-1][0], edges[i-1][1]);
        }
        return result;
    }

    private boolean isConnected(int i, int j) {
        return find(i) == find(j);
    }


    private void unionElements(int i, int j) {
        int iP = find(i);
        int jP = find(j);
        if (iP != jP) {
            for (int k = 0; k < p.length; k++) {
                if (p[k] == iP) {
                    p[k] = jP;
                }
            }
        }
    }

    private int find(int i) {
        if (p[i] != i) {
            return find(p[i]);
        }
        return p[i];
    }
}


 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LeetCode 查并集系列 朋友圈 冗余链接等 的相关文章

  • ROS入门之Cmakelist说明

    Cmakelist http wiki ros org catkin CMakeLists txt 1 Overall Structure and Ordering Your CMakeLists txt file MUST follow
  • DELL 暗夜精灵无法进入BIOS系统

    1 1 开始菜单 设置 2 单击 更新和安全 3 单击右边列表项中的 恢复 4 单击左侧的 立即重启 xff0c 这时电脑就会立即重启 xff0c 所以单击前请保存好未保存文件 5 当电脑重启之后会进入如下界面 xff0c 单击 疑难解答
  • Simulink永磁同步电机控制仿真系列八:使用自抗扰控制(adrc)实现速度闭环以及扰动估计

    引言 最近对环路进行了一些思考 xff0c 我们知道对于永磁同步电机的电流环控制 xff0c 往往假定电流环的控制对象是电阻和电感的串联 xff0c 这样的一个系统开环响应类似于一阶惯性系统 xff0c 适合使用pi控制 xff0c 并且可
  • STM32之RTC实时时钟

    RTC实时时钟简介 STM32的RTC外设 实质是一个掉电后还继续运行的定时器 从定时器的角度来看 相对于通用定时器TIM外设 它的功能十分简单 只有计时功能 也可以触发中断 但是从掉电还能继续运行来看 它是STM32中唯一一个具有这个功能
  • VS2019 错误 MSB8066 自定义生成已退出,代码为 3

    最近使用VS2019调试一个项目 xff0c 一直遇到以下错误 xff1a 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 MSB8066 D MyItems CDMatrix Build CMakeFiles 3800edc586
  • RTOS与linux区别

    一句话解释 xff1a linux是分时系统 xff0c 不过可以通过配置内核改成实时 嵌入式Linux 系统是在原来Linux的发行版本之上进行了优化和改进的 xff0c 用于嵌入式的移动终端等设备的嵌入式Linux系统现在基本上都是实时
  • QT绘图控件QWT的安装及配置

    1 QWT库下载 解压下载的压缩包 xff0c 我们可以看到里面包含多个文件夹 有源码 有参考程序 有说明文档等等 xff0c 有时间建议把参考程序都看一下 xff0c 这样都每个控件有什么功能都很熟悉 2 QWT编译 网上介绍QWT编译有
  • QT多线程的使用(moveToThread方法)

    QT有两种实现多线程的方法 xff0c 一种是 子类化QThread xff0c 然后去重写run函数 xff0c 实现多线程 一种是 子类化QObject xff0c 然后使用moveToThread函数实现多线程 由于QT官方推荐使用第
  • 嵌入式Linux学习1——Linux常用指令1

    写在前面 xff1a Linux本系列的所有学习内容都是我在购买 正点原子Alpha Linux开发板 后 xff0c 根据官方提供的资料 整理而来 后面将不再做介绍 目录 ls xff1a 用于显示当前目录下的内容 a xff1a 显示当
  • 嵌入式Linux学习2——Linux常用指令2

    目录 touch xff1a touch命令用来创建空文件 cp xff1a cp命令用来复制文件或目录 rm xff1a rm命令用于删除一个文件或者目录 mkdir xff1a 用于创建文件夹 mv xff1a mv命令用来为文件或目录
  • 基于STM32分析栈、堆、全局区、常量区、代码区、RAM、ROM

    目录 总体介绍 栈区 xff08 stack xff09 堆区 xff08 heap xff09 全局区 xff08 静态区 xff09 bss段 data段 常量区 代码区 RAM和ROM Flash Memory的物理特性 RAM RO
  • VS2013(Visual Studio 2013)官方中文旗舰版安装激活方法

    dio 2013旗舰版 VS2013 xff08 Visual Studio 2013 xff09 官方中文旗舰版安装激活方法 1 下载后得到的是ISO文件 xff0c 直接解压缩或用虚拟光驱加载运行都可以 2 无所不藏在这里直接解压 xf
  • git服务器(gitea)安装说明

    需要用到的软件 需要用到的软件有 gitea 1 12 3 windows 4 0 amd64 exenssm exeGit 2 28 0 64 bit exe 这些软件的具体功能在后面安装的时候会提及 软件都已经放到了 软件包 文件夹中
  • 实战篇 | 基于freeRTOS的多任务事件传输demo(附代码)

    之前分享了很多关于freeRTOS的知识 xff0c 那么我们怎么在实战中去写代码呢 xff1f 本篇文章重在对基于freeRTOS的架构代码的解析 整个功能如下图 xff1a 为什么要用freeRTOS 在实际项目中 xff0c 如果程序
  • FMCW-距离估计

    距离估计 FMCW雷达工作原理 如上图所示 xff0c 圈1是一个信号产生器 xff0c 用于产生一个线性调频脉冲信号 xff08 频率随时间义线性方式增长的正弦波 xff09 xff0c 经圈2发射天线发送出去 xff0c 并且和圈3接收
  • 卡尔曼滤波器从入门到放弃

    目录 前言 个人总结 总结卡尔曼滤波器使用流程 从一维卡尔曼滤波器 不带过程噪声的一维卡尔曼滤波器 EXAMPLE 5 ESTIMATING THE HEIGHT OF A BUILDING 数值例子 xff1a 一维卡尔曼滤波器的完整模型
  • IAR下载算法制作

    IAR下载算法制作 作者 Lucas 时间 2020 12 06 17 06 18 摘要 本文档主要介绍如何在IAR环境下制作QSPI下载算法 本文使用到的硬件 软件如下 编译器 xff1a IAR 8 32 单片机 xff1a STM32
  • clang-format格式化工程代码

    zClang Format 最近在考虑团队代码风格的问题 xff0c 无意间发现了一个代码格式化神器 clang format 工具 在了解clang format工具之前 xff0c 我们先来了解一下什么是clang xff0c 什么是L
  • (转)跟我一起写 Makefile(一)(陈皓)

    本问转载自陈皓大神的跟我一起写 Makefile xff08 一 xff09 概述 什么是makefile xff1f 或许很多Winodws的程序员都不知道这个东西 xff0c 因为那些Windows的IDE都为你做了这个工作 xff0c
  • C语言 volatile的作用与使用场景

    今天完成公司的任务 xff0c 突然想起来在调试过程中遇到了一个问题是这样的 xff1a 我在主函数里面写了一个while xff08 x xff09 的循环 xff0c 想在中断里面去改变这个变量x xff0c 以达到主函数里面退出whi

随机推荐