力扣刷题-128.最长连续序列、并查集

2023-10-26

一.并查集

  顾名思义:并:就是合并,查:就是查找,集:就是集合。并查集是一种树形的数据结构,支持以下两种操作:

  • 查找:确定某个元素处于哪个子集
  • 合并:将两个子集合并成一个集合
  1. 初始化
    集合就是一些具有相同特征的元素构成的圈子,然后用其中某个元素作为整个圈子的代表。
    在这里插入图片描述
    如上图所示:初始的时候每个元素各自构成一个集合,自己为自己代言。
  2. 合并
    可以用树形结构来表示整个集合,每个元素代表一个节点,用根节点代表整个集合。合并两个元素就是对两个元素所在的集合进行合并,即直接把一个集合的根节点作为另外一个集合根节点的子节点。
    在这里插入图片描述
    如上图所示:元素1 和元素2 合并的结果就是,合并元素1、元素2 所在的集合,元素1为所属集合的根节点。
  3. 查找
    查找就是查询某个元素所在集合,即查找所在集合的根节点。
    在这里插入图片描述
    如上图所示,查找4所在集合的根节点,即对树形结构进行遍历逐层找父节点。
  4. 路径优化
    一个集合对应一个树形结构,但是我们并不真的关注谁是谁的父节点,而是对树形结构整体进行关注。因此我们可以把查找路径上的所有节点都直接和根节点相连,以缩短下次查找路径,如下图所示:
    在这里插入图片描述

二.并查集的实现

  1. 概述
    对于每个元素仅需要记录其父节点即可,因此可以使用map来记录所有节点以及其父节点。
    并查集的查找和合并的时间复杂度可以认为是O(1)​。​
  2. 代码示例
    class unionfind
    {
    private:
        unordered_map<int,int> root_map;//节点id—父节点id
    public:
        //元素初始化
        void addnode(int i)
        {
            if( root_map.find(i) == root_map.end())
            {
                root_map[i] = i;//初始化父节点为自身id
            }
        }
        //判断x、y是否属于同一集合,判断其祖先节点是否相等
        bool checkxy( int x,int y)
        {
            x = getroot(x);//找x祖先节点
            y = getroot(y);//找y祖先节点
            if( x== y)
            {
                return true;
            }
            return false;
        }
        //合并元素x、y
        void mergexy( int x,int y)
        {
            x = getroot(x);//找x祖先节点
            y = getroot(y);//找y祖先节点
            if( x== y)//祖先相同则属于同一集合
            {
                return;
            }
            else
            {
                root_map[y] = x;//修改y的祖先节点为x
                return ;
            }
        }
        //查询元素祖先节点
        int getroot( int i)
        {
            if( root_map[i] == i)
            {
                return i;
            }
            else
            {
                root_map[i] = getroot(root_map[i]);//路径压缩
                return root_map[i];
            }
        }
    };
    

三.应用举例

给定一个未排序的整数数组,找出最长连续序列的长度,要求算法的时间复杂度为 O(n)
示例:
输入: [100, 4, 200, 1, 3, 2]
输出: 4
解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。
来源:力扣(LeetCode)第128题

  本题可以采用并查集来实现,首先初始化所有元素父节点为自身,然后遍历数组中每个元素,查找比其值大1的元素是否存在,若存在则两个元素合并,最终比较合并后每个集合元素数量即可。

class Solution {
public:
    unordered_map<int,int> father_map;//节点-父节点
    unordered_map<int,int> child_count;// 节点-子节点个数
    int longestConsecutive(vector<int>& nums) {
        int res = 1;
        if( nums.size() == 0) return 0;
        for(int i = 0;i < nums.size();i++)
        {
            father_map[nums[i]] = nums[i];
            child_count[nums[i]] = 1;
        }
        for(int i = 0;i < nums.size();i++)
        {
             if( father_map.find(nums[i]+1) != father_map.end())
             {
                 res = max (res,mergexy(nums[i],nums[i]+1));
             }
        }
        return res;
    }
    int getfather(int i)
    {
        if( father_map[i] == i)
        {
            return i;
        }
        else
        {
            father_map[i] = getfather(father_map[i]);
            return father_map[i] ;
        }
    }
    int mergexy(int x,int y)
    {
        x = getfather(x);
        y = getfather(y);
        if( x == y )
        {
            return child_count[x];
        }
        else
        {
            father_map[y] = x;
            child_count[x] +=child_count[y];
            return child_count[x];
        }
    }
};

在这里插入图片描述

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

力扣刷题-128.最长连续序列、并查集 的相关文章

随机推荐

  • 提领类型双关的指针将破坏重叠规则——strict-aliasing

    转载请保留本行原始出处声明信息 http www zeali net entry 454 MaDe1nZEAL warning dereferencing type punned pointer will break strict alia
  • 怎么理解离散数据?

    离散数据是指数据值只能取有限的 可数的数值 而不能取到连续的数值 相对的 连续数据可以取到任意数值 离散数据是在一个固定的集合中取值 集合通常是整数集或有限的枚举集 例如 一个人的家庭成员数量就是一个离散数据 它只能取到整数值 如0 1 2
  • JS的类型转换和float取n位小数

    javascript中的变量都是弱类型 所有的变量都声明为var 在类型转换过程中就没有java那么方便 它是通过 parseInt 变量 parseFloat 变量 等方法来进行类型转换的 注意 没有parseDouble 变量 这种类型
  • k8s deployment Strategy 更新策略

    k8s更新策略 https kubernetes io zh docs concepts workloads controllers deployment Strategy spec strategy specifies the strat
  • vue修改富文本中的元素样式

    富文本编辑器目前应用很广泛 而有时候我们想要对其中的一些元素的样式进行修改 就会遇到问题 首先 直接修改是不可行的 因为是用v html标签进行渲染的 无法直接获取到 在修改的时候 一般是按标签进行修改 当然 也可以按class和id等 这
  • python:从键盘输入学生的成绩,转换成 5 个等级输出。A(90~100),B(80~89),C(70~79),D(60~69),E(0~59)。试用嵌套分支结构实现。

    grades eval input 请输入你的成绩 if 90 lt grades lt 100 print A elif 80 lt grades lt 90 print B elif 70 lt grades lt 79 print C
  • 前置机

    前置机这个概念一般在银行 券商 电信运营商那里用的比较多 这些地方都有很多后台核心处理系统 对外提供各种接口服务 如果我有某种业务接口需要跟他们的后台系统打交道 要从我们的外部网络访问他们的后台系统 这些单位是绝对不允许的 这个时候 他们要
  • Unity中协程与线程的区别

    本文转载自 https blog csdn net qq 25122429 article details 80481443 协同程序 coroutine 与多线程情况下的线程比较类似 有自己的堆栈 自己的局部变量 有自己的指令指针 IP
  • 【编程之路】面试必刷TOP101:贪心算法(95-96,Python实现)

    面试必刷TOP101 贪心算法 95 96 Python实现 95 分糖果问题 小试牛刀 95 1 贪心思想 要想分出最少的糖果 利用贪心思想 肯定是相邻位置没有增加的情况下 大家都分到1 相邻位置有增加的情况下 分到糖果数加1就好 什么情
  • Java-内部类

    Java 内部类 1 概念 Java中允许将一个类A声明在另外一个类B中 则类A就是内部类 类B 就称为外部类 内部类的分类 成员内部类 一方面作为外部类的成员 可以调用外部类的结构 可以被static修饰 可以被四种不同的权限修饰符 pu
  • 在手机上运行Python--安卓linux终端Termux

    今天突发奇想 想找一种在手机上运行Python的工具 于是发现了这个安卓端的linux终端 Termux 可以在手机上实现一个微型的linux终端 网上已经有不少教程了 我在这里做一下汇总 1 安装Python以及常用的package nu
  • Python+OpenCV3简单手势识别

    文章目录 安装相关库 原理简述 代码 效果实现 今天教大家一个有趣的玩法 如何利用Python opencv3实现简单的手势识别 当然网上也有相关教程 但绝大多数给出的代码拿来之后你是不能直接用的 这对于拿来主义的同学来说简直太 禽兽 了
  • python rpy2_Python&R语言-rpy2使用示例

    前言 Python编程灵活方便 R的模型方法众多 如何将两者结合起来 发挥更大的作用 值得探索 Python可以直接调用R的函数 R是开源项目 肯定会有一些第三方库实现Python与R互通 需要在python中调用R 实在是一种无奈的选择
  • vue3+TSX+element-plus(DateTimePicker)做一个时间范围选择器

    element plus包括element ui支持时间范围选择 把type指定成datetimerange就行了 但是它不支持单个选择 也许unlink panels这个配置有用 但我是用TSX写的 传了个true进去没用 怎么试都不行
  • 20张图带你了解JVM运行时数据区(上)

    我们的JVM系列已经断更好几天了 小伙伴们在后台疯狂私信阿Q 想看后续内容 今天它来了 相信大家在上篇文章中已经对类加载子系统有了清晰的认识 接下来就让我们来揭开 运行时数据区 的神秘面纱吧 运行时数据区总览 内存是非常重要的系统资源 是硬
  • GC overhead limit exceeded问题

    Java运行时环境内置了 垃圾收集 GC 模块 上一代的很多编程语言中并没有自动内存回收机制 需要程序员手工编写代码来进行内存分配和释放 以重复利用堆内存 在Java程序中 只需要关心内存分配就行 如果某块内存不再使用 垃圾收集 Garba
  • vue watermark水印添加

    vue 水印实现 Vue项目在页面添加水印功能 不允许操作dom关闭水印 1 添加watermark dom插件 npm i watermark dom save 引用 watermark dom import watermark from
  • lsqcurvefit函数的基本用法

    本文讲解lsqcurvefit函数的基本用法 一 lsqcurvefit函数的简单使用格式 x lsqcurvefit fun x0 xdata ydata x resnorm lsqcurvefit fun x0 xdata ydata
  • 线程安全性的基本概念

    线程安全性 我们总是说要编写线程安全的代码 有时候也会讨论某个类是不是线程安全的 那到底什么是线程安全性呢 网上有很多说法 可以被多个线程调用 并且线程之间不会出现错误的交互 多个线程调用时 不需要做额外的动作等等 但这话 明明什么都说了
  • 力扣刷题-128.最长连续序列、并查集

    一 并查集 顾名思义 并 就是合并 查 就是查找 集 就是集合 并查集是一种树形的数据结构 支持以下两种操作 查找 确定某个元素处于哪个子集 合并 将两个子集合并成一个集合 初始化 集合就是一些具有相同特征的元素构成的圈子 然后用其中某个元