想要精通算法和SQL的成长之路 - 最长连续序列

news2024/11/17 23:35:50

想要精通算法和SQL的成长之路 - 最长连续序列

  • 前言
  • 一. 最长连续序列
    • 1.1 并查集数据结构创建
    • 1.2 find 查找
    • 1.3 union 合并操作
    • 1.4 最终代码

前言

想要精通算法和SQL的成长之路 - 系列导航
并查集的运用

一. 最长连续序列

原题链接

在这里插入图片描述
这个题目,如何使用并查集是一个小难点,我们可以这么想:

  • 对于数组中的每一个元素,在初始化的时候,根节点是它本身。以它为根节点的最长连续序列是1。
  • 在经历过一系列的合并操作之后,以示例1来说,元素4的根节点就是元素1。
  • 那么我们合并操作,合并的对象是谁?注意题目要求的是连续序列。那么针对每个元素num,我进行union(num,num+1)即可。
  • 由于题目要求的是最长的连续序列,因此我们可以在并查集中维护一个max最大值。在合并操作的时候更新它。
  • 由于数组内元素的跳跃性,我们可以用一个HashMap替代并查集的int[]数组。

1.1 并查集数据结构创建

class UnionFind {
    private Map<Integer, Integer> parent;
    private Map<Integer, Integer> rank;
    private int max;

    public UnionFind(int[] nums) {
        max = 1;
        HashMap<Integer, Integer> tmpParent = new HashMap<>();
        HashMap<Integer, Integer> tmpRank = new HashMap<>();
        // 初始化操作:每个元素的根节点是它本身。并且以该元素作为根节点时的最长连续序列长度是1
        for (int num : nums) {
            tmpParent.put(num, num);
            tmpRank.put(num, 1);
        }
        parent = tmpParent;
        rank = tmpRank;
    }
}

1.2 find 查找

因为我们在合并过程中,进行union(num,num+1)操作,以nums = [100,4,200,1,3,2]为例,那么100+1 = 101,101这个元素是否在集合当中呢?

我们看下常规的函数:

public int find(int x) {
    while (x != parent[x]) {
        x = parent[x];
    }
    return x;
}

而我们在本题当中,使用HashMap作为替换存储,同时我们还需要考虑到对象不存在的情况,代码如下

public int find(int x) {
    // 因为我们是以每个元素 + 1 来合并的,因此+1后的元素不一定存在于集合当中。
    // 这里就要特判,否则就会导致NPE,null和int进行 == 比较,会NPE
    if (!parent.containsKey(x)) {
        return x;
    }
    if (parent.get(x) == x) {
        return x;
    }
    parent.put(x, find(parent.get(x)));
    return parent.get(x);
}

1.3 union 合并操作

public void union(int x, int y) {
	// 如果不存在,也要直接返回
    if (!parent.containsKey(y)) {
        return;
    }
    int rootX = find(x);
    int rootY = find(y);
    // 是同一个根节点,直接返回
    if (rootX == rootY) {
        return;
    }
    // 区间合并,算出合并后的连续序列长度
    int tmpSum = rank.get(rootY) + rank.get(rootX);
    if (rank.get(rootX) > rank.get(rootY)) {
        rank.put(rootX, tmpSum);
        // 更新rootY的根节点为rootX
        parent.put(rootY, rootX);
    } else {
        rank.put(rootY, tmpSum);
        parent.put(rootX, rootY);
    }
    // 合并的同时还要维护max值(最长连续序列长)
    max = Math.max(max, tmpSum);
}

1.4 最终代码

public int longestConsecutive(int[] nums) {
    if (nums.length == 0) {
        return 0;
    }
    UnionFind unionFind = new UnionFind(nums);
    for (int num : nums) {
    	// 将当前元素和 +1后的值进行合并
        unionFind.union(num, num + 1);
    }
    return unionFind.max;
}

class UnionFind {
    private Map<Integer, Integer> parent;
    private Map<Integer, Integer> rank;
    private int max;

    public UnionFind(int[] nums) {
        max = 1;
        HashMap<Integer, Integer> tmpParent = new HashMap<>();
        HashMap<Integer, Integer> tmpRank = new HashMap<>();
        // 初始化操作:每个元素的根节点是它本身。并且以该元素作为根节点时的最长连续序列长度是1
        for (int num : nums) {
            tmpParent.put(num, num);
            tmpRank.put(num, 1);
        }
        parent = tmpParent;
        rank = tmpRank;
    }

    public int find(int x) {
        // 因为我们是以每个元素 + 1 来合并的,因此+1后的元素不一定存在于集合当中。
        // 这里就要特判
        if (!parent.containsKey(x)) {
            return x;
        }
        if (parent.get(x) == x) {
            return x;
        }
        parent.put(x, find(parent.get(x)));
        return parent.get(x);
    }

    public void union(int x, int y) {
        if (!parent.containsKey(y)) {
            return;
        }
        int rootX = find(x);
        int rootY = find(y);
        // 是同一个根节点
        if (rootX == rootY) {
            return;
        }
        int tmpSum = rank.get(rootY) + rank.get(rootX);
        if (rank.get(rootX) > rank.get(rootY)) {
            rank.put(rootX, tmpSum);
            parent.put(rootY, rootX);
        } else {
            rank.put(rootY, tmpSum);
            parent.put(rootX, rootY);
        }
        max = Math.max(max, tmpSum);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1060006.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

带你10分钟学会红黑树

前言&#xff1a; 我们都知道二叉搜索树&#xff0c;是一种不错的用于搜索的数据结构&#xff0c;如果二叉搜索树越接近完全二叉树&#xff0c;那么它的效率就会也高&#xff0c;但是它也存在的致命的缺陷&#xff0c;在最坏的情况下&#xff0c;二叉搜索树会退化成为单链表&am…

Spring三大核心组件

Spring架构图 Spring三大核心组件分别为&#xff1a;Core、Beans和Context 1. Core&#xff08;核心&#xff09;&#xff1a; 思想&#xff1a;Core组件的核心思想是控制反转&#xff08;IoC&#xff09;和依赖注入&#xff08;DI&#xff09;。它将对象的创建、组装和管理的…

【图像处理】使用各向异性滤波器和分割图像处理从MRI图像检测脑肿瘤(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

番外--Task2:

任务&#xff1a;root与普通用户的互切&#xff08;区别&#xff09;&#xff0c;启动的多用户文本见面与图形界面的互切命令&#xff08;区别&#xff09;。 输入图示命令&#xff0c;重启后就由图形界面转成文本登录界面&#xff1b; 输入图示命令&#xff0c;重启后就由文本…

Netron【.pt转.torchscript模型展示】

Netron是一个模型的展示工具&#xff0c;它有网页版和app版&#xff1a; 网页版&#xff1a;Netron app版&#xff1a;GitHub - lutzroeder/netron: Visualizer for neural network, deep learning, and machine learning models 直接用网页版吧&#xff0c;还不用安装。 它可…

【kubernetes】CRI OCI

1 OCI OCI(Open Container Initiative)&#xff1a;由Linux基金会主导&#xff0c;主要包含容器镜像规范和容器运行时规范&#xff1a; Image Specification(image-spec)Runtime Specification(runtime-spec)runC image-spec定义了镜像的格式&#xff0c;镜像的格式有以下几…

竞赛选题 机器视觉的试卷批改系统 - opencv python 视觉识别

文章目录 0 简介1 项目背景2 项目目的3 系统设计3.1 目标对象3.2 系统架构3.3 软件设计方案 4 图像预处理4.1 灰度二值化4.2 形态学处理4.3 算式提取4.4 倾斜校正4.5 字符分割 5 字符识别5.1 支持向量机原理5.2 基于SVM的字符识别5.3 SVM算法实现 6 算法测试7 系统实现8 最后 0…

【SpringBoot】配置文件详解

配置文件详解 一. 配置文件作用二. 配置文件的格式1. properties 配置文件说明①. properties 基本语法②. 读取配置⽂件③. properties 缺点 2. yml 配置⽂件说明①. yml 基本语法②. yml 使用进阶 3. properties VS yml 三. 设置不同环境的配置⽂件 一. 配置文件作用 整个项…

jsbridge实战1:xcode swift 构建iOS app

[[toc]] 环境安装 macOs: 10.15.5 xcode: 11.6 demo:app 创建 hello world iOS app 创建工程步骤 选择&#xff1a;Create a new Xcode project选择&#xff1a;iOS-> single View App填写&#xff1a; project name: swift-app-helloidentifer: smile 包名language: s…

基于Android的香格里拉美食分享APP/美食分享平台/基于android的美食平台

摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的APP应运而生&#xff0c;各行各业相继进入信息管理时代&#x…

Youtube视频下载工具分享-油管视频,音乐,字幕下载方法汇总

YouTube视频下载方法简介 互联网上存在很多 YouTube 下载工具&#xff0c;但我们经常会发现自己收藏的工具没过多久就会失效&#xff0c;我们为大家整理的这几种方法&#xff0c;是存在时间较久并且亲测可用的。后续如果这些工具失效或者有更好的工具&#xff0c;我们也会分享…

【多线程进阶】死锁问题

文章目录 前言1. 什么是死锁1.1 死锁的三种典型情况 2. 死锁产生的必要条件3.如何解决死锁问题总结 前言 上文锁策略中, 当谈到可重入锁和不可重入锁时, 我们引入了一个 “死锁” 的概念, 当针对一把不可重入锁进行连续两次的加锁行为时, 就会产生死锁. 本文就重点来讲解一下…

QT调用python程序出现问题Failed to get function

问题描述&#xff1a; 1.python中程序运行正常但在QTC的配置中使用Python.h调用python程序时出现Failed to get function问题&#xff0c;去掉python中某个包的应用就可以&#xff0c;比如&#xff1a; python部分程序&#xff1a; import os.path import pandas as pd如果在…

第十二届2023软件杯国家二等奖赛后感想总结

一&#xff0c;相关链接 软件杯官网&#xff1a;软件杯大赛官网 (cnsoftbei.com) 金蝶赛道&#xff1a;金蝶云苍穹开发者门户 (kingdee.com) 二&#xff0c;个人介绍 首先我是个双非院校的学生&#xff0c;专业为计算机科学与技术&#xff0c;打这个比赛是在大二下的暑假开始的…

【10】c++设计模式——>依赖倒转原则

关于依赖倒转原则&#xff0c;对应的是两条非常抽象的描述&#xff1a; 1.高层模块不应该依赖低层模块&#xff0c;两个都应该依赖抽象。 2.抽象不应该依赖细节&#xff0c;细节应该依赖抽象。 先用人话解释一下这两句话中的一些抽象概念&#xff1a; 1.高层模块&#xff1a;可…

【算法练习Day11】滑动窗口最大值前 K 个高频元素

​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 滑动窗口最大值前 K 个高频…

stm32之HAL库操作PAJ75620

一、模块简介 手势模块PAJ7620主要利用IIC或SPI协议来实现数据的传输&#xff0c;本实验用的模块是以IIC来进行信息传输。支持电压从2.8v到3.6v, 正常可以选择3.3v。检测的距离从5到15cm, 可以检测9种手势&#xff0c;包括 右&#xff1a;编码为 0x01左&#xff1a;编码为 0x0…

FDM3D打印系列——黄金弗利萨

大家好&#xff0c;我是阿赵。   国庆期间&#xff0c;在家打印了一个黄金弗利萨的3D模型&#xff0c;和大家分享一下。模型在创想云上面下载的。 使用的设备依然是创想三维的Sermoon V1 Pro&#xff0c;使用的打印材料是创想三维的PLA高速打印素材。 不得不说&#xff0c;…

经典场的量子化

专栏目录: 高质量文章导航-持续更新中-CSDN博客 前置:复指数引起的思考 往指数函数e上丢一个复矢量出来的也是一个复矢量 其定义参考之前的文章群论-李代数_GZVIMMY的博客-CSDN博客 进一步了解下复矢量空间 首先了解下复球面(用一个球表示了所有的复数) 形如[x,y]的二维实…

科普rabbitmq,rocketmq,kafka三者的架构比较

对比 架构对比 从架构可以看出三者有些类似&#xff0c;但是在细节上有很多不同。下面我们就从它们的各个组件&#xff0c;介绍它们&#xff1a; RabbitMQ&#xff0c;是一种开源的消息队列中间件。下面是RabbitMQ中与其相关的几个概念&#xff1a; 1.生产者&#xff08;P…