使用Arrays.Sort并定制Comparator排序解决合并区间

合并区间-力扣算法题56题

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

示例 1:

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。

提示:

  • 1 <= intervals.length <= 104
  • intervals[i].length == 2
  • 0 <= starti <= endi <= 104

java实现算法代码

class Solution {
    public int[][] merge(int[][] intervals) {
        if (intervals.length == 0) {
            return new int[0][2];
        }
        Arrays.sort(intervals, new Comparator<int[]>() {
            public int compare(int[] interval1, int[] interval2) {
                return interval1[0] - interval2[0];
            }
        });
        List<int[]> merged = new ArrayList<int[]>();
        for (int i = 0; i < intervals.length; ++i) {
            int L = intervals[i][0], R = intervals[i][1];
            if (merged.size() == 0 || merged.get(merged.size() - 1)[1] < L) {
                merged.add(new int[]{L, R});
            } else {
                merged.get(merged.size() - 1)[1] = Math.max(merged.get(merged.size() - 1)[1], R);
            }
        }
        return merged.toArray(new int[merged.size()][]);
    }
}

算法思路(力扣的思路)

如果我们按照区间的左端点排序,那么在排完序的列表中,可以合并的区间一定是连续的。如下图所示,标记为蓝色、黄色和绿色的区间分别可以合并成一个大区间,它们在排完序的列表中是连续的: 

 

算法

我们用数组 merged 存储最终的答案。

首先,我们将列表中的区间按照左端点升序排序。然后我们将第一个区间加入 merged 数组中,并按顺序依次考虑之后的每个区间:

如果当前区间的左端点在数组 merged 中最后一个区间的右端点之后,那么它们不会重合,我们可以直接将这个区间加入数组 merged 的末尾;

否则,它们重合,我们需要用当前区间的右端点更新数组 merged 中最后一个区间的右端点,将其置为二者的较大值。

正确性证明

上述算法的正确性可以用反证法来证明:在排完序后的数组中,两个本应合并的区间没能被合并,那么说明存在这样的三元组 (i,j,k) 以及数组中的三个区间 a[i],a[j],a[k] 满足 i<j<k 并且 (a[i],a[k])可以合并,但 (a[i],a[j]) 和 (a[j],a[k]) 不能合并。这说明它们满足下面的不等式:

a[i].end<a[j].start(a[i] 和 a[j] 不能合并)a[j].end<a[k].start(a[j] 和 a[k] 不能合并)a[i].end≥a[k].start(a[i] 和 a[k] 可以合并)
                        a[i].end<a[j].start(a[i] 和 a[j] 不能合并)
                        a[j].end<a[k].start(a[j] 和 a[k] 不能合并)
                        a[i].end≥a[k].start(a[i] 和 a[k] 可以合并)
我们联立这些不等式,可以得到:

                                        a[i].end<a[j].start≤a[j].end<a[k].start
产生了矛盾!这说明假设是不成立的。因此,所有能够合并的区间都必然是连续的。

我的思路

1.先判断该 intervals是否为空,为空则返回一个空的二维数组int[0][2]

2.不为空的话,先用Array.sort(T[] a,Comparator<? super T> c)来定制一个只比较数组的最左端并使用升序排序的Compare排序器

3.之后将二维数组封装在一个List集合里面,进行下一步比较

4.有两种情况

        4.1. 如果第一个区间的最右端的值小于下一个区间的最左端的值,则在List集合中再添加一个区间

        4.2. 如果第一个区间的最右端的值大于等于下一个区间最左端的值,则将第一个区间最右端的值修改为下一个区间最右端的值

5.将List转换为数组并以二维数组的形式返回即可

使用方法Arrays.sort和Comprator

Arrays.sort使用文档

  • public static <T> void sort​(T[] a, Comparator<? super T> c)
    • 根据指定比较器引发的顺序对指定的对象数组进行排序。 数组中的所有元素都必须是指定比较相互比较的 (即, c.compare(e1, e2)不得抛出ClassCastException任何元件e1e2阵列中)。

      这种保证是稳定的 :相同的元素不会因排序而重新排序。

      实现注意事项:此实现是一个稳定的,自适应的迭代合并输出,当输入数组部分排序时,需要远远少于n lg(n)的比较,同时在输入数组随机排序时提供传统mergesort的性能。 如果输入数组几乎排序,则实现需要大约n次比较。 临时存储要求从几乎排序的输入数组的小常量到随机排序的输入数组的n / 2个对象引用不等。

      该实现在其输入数组中具有升序和降序的相同优势,并且可以利用同一输入数组的不同部分中的升序和降序。 它非常适合合并两个或多个排序数组:只需连接数组并对结果数组进行排序。

      参数类型

      T - 要排序的对象的类

      参数

      a - 要排序的数组

      c - 用于确定阵列顺序的比较器。 null值表示应使用元素' natural ordering 。

      异常

      ClassCastException - 如果数组包含使用指定比较器无法 相互比较的元素

      IllegalArgumentException - (可选)如果发现比较器违反了Comparator合同

 Comprator使用文档

  • public interface Comparator<T>
    比较函数,它对某些对象集合施加总排序 。 可以将比较器传递给排序方法(例如Collections.sortArrays.sort ),以便精确控制排序顺序。 比较器还可用于控制某些数据结构的顺序(例如sorted setssorted maps ),或者为没有natural ordering的对象集合提供排序。

    比较器c对一组元素S施加的排序被认为与等号一致,当且仅当c.compare(e1, e2)==0具有与e1.equals(e2)e1e2S中的S相同的布尔值时。

    当使用能够强加与equals不一致的排序的比较器来排序有序集(或有序映射)时,应该谨慎行事。 假设具有显式比较器c的有序集(或有序映射)与从集合S提取的元素(或键) S 。 如果cS的排序与equals不一致,则排序集(或有序映射)将表现得“奇怪”。 特别是有序集(或有序映射)将违反集合(或映射)的一般合同,其定义为equals

    例如,假设有两个元素ab ,使(a.equals(b) && c.compare(a, b) != 0)为空TreeSet ,比较器为c 。 第二个add操作将返回true(并且树集的大小将增加)因为ab在树集的视角中不相等,即使这与Set.add方法的规范相反。

    注意:这通常是一个好主意比较,也能实现java.io.Serializable ,因为它们可能被用来作为排序的序列化数据结构的方法(如TreeSetTreeMap )。 为了使数据结构成功序列化,比较器(如果提供)必须实现Serializable

    对于数学上的倾斜,即限定了施加顺序给定的比较器的关系 c上一组给定对象强加S是:

      {(x, y) such that c.compare(x, y) <= 0}. 
    此总订单的是:
      {(x, y) such that c.compare(x, y) == 0}. 
    它从合同紧跟compare ,该商数是一个等价关系 S ,并且实行排序是全序 S 。 当我们说cS施加的排序与equals一致时 ,我们的意思是排序的商是由对象' equals(Object)方法定义的等价关系:
      {(x, y) such that x.equals(y)}. 

    Comparable不同,比较器可以选择允许比较空参数,同时保持对等关系的要求。

声明

部分算法思路摘自力扣(位置在算法思路这个目录里),其余均为个人创作

作者:力扣官方题解
链接:https://leetcode.cn/problems/merge-intervals/
来源:力扣(LeetCode)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

新手必看!!附源码!!STM32通用定时器-比较输出PWM

一、什么是PWM? PWM&#xff08;脉冲宽度调制&#xff09;是一种用于控制电子设备的技术。它通过调整信号的脉冲宽度来控制电压的平均值。PWM常用于调节电机速度、控制LED亮度、产生模拟信号等应用。 二、PWM的原理 PWM的基本原理是通过以一定频率产生的脉冲信号&#xff0…

PHP 语法||PHP 变量

PHP 脚本在服务器上执行&#xff0c;然后将纯 HTML 结果发送回浏览器。 基本的 PHP 语法 PHP 脚本可以放在文档中的任何位置。 PHP 脚本以 <?php 开始&#xff0c;以 ?> 结束&#xff1a; <?php // PHP 代码 ?> 值得一提的是&#xff0c;通过设定php.ini的相…

Spring配置其他注解Spring注解的解析原理

Spring配置其他注解 Primary注解用于标注相同类型的Bean优先被使用权&#xff0c;Primary是Spring 3.0引入的&#xff0c;与Component和Bean一起使用&#xff0c;标注该Bean的优先级更高&#xff0c;则在通过类型获取Bean或通过Autowired根据类型进行注入时&#xff0c;会选用优…

什么是数据确权?

在数字化时代&#xff0c;数据已经成为一种新型资产&#xff0c;”新的石油“&#xff0c;具有巨大的价值&#xff0c;未来世界经济竞争一定程度上是数字经济的竞争&#xff0c;而非工业的竞争。数据相关法律制度&#xff0c;尚且还不完整&#xff0c;推动数字经济的发展&#…

YOLOv8训练自己的目标检测数据集

YOLOv8训练自己的目标检测数据集 目录标题 源码下载环境配置安装包训练自己的数据集数据集文件格式数据集文件配置超参数文件配置训练数据集命令行训练脚本.py文件训练 进行detect显示detect的效果 源码下载 YOLOv8官方的GitHub代码&#xff0c;同时上面也有基础环境的配置要…

VOC数据集和COCO数据集直接的相互转换

VOC数据集格式 get_list.py import os import random import shutil# 设置随机种子 random.seed(1000)# 判断Annotations和JpegImages是否对应 train_precent=0.8 label_path= "../../Annotations" print(os.path.abspath(label_path)) save="../Main" pr…

前端工程、静态代码、Html页面 打包成nginx 的 docker镜像

1. 创建一个 mynginx的目录 2. 将前端代码文件夹&#xff08;比如叫 front &#xff09;复制到 mynginx 目录下 3. 在mynginx 目录下创建一个名为Dockerfile 的文件&#xff08;文件名不要改&#xff09;&#xff0c;文件内容如下&#xff1a; # 使用官方的 Nginx 镜像作为基…

深度学习图像分类算法研究与实现 - 卷积神经网络图像分类 计算机竞赛

文章目录 0 前言1 常用的分类网络介绍1.1 CNN1.2 VGG1.3 GoogleNet 2 图像分类部分代码实现2.1 环境依赖2.2 需要导入的包2.3 参数设置(路径&#xff0c;图像尺寸&#xff0c;数据集分割比例)2.4 从preprocessedFolder读取图片并返回numpy格式(便于在神经网络中训练)2.5 数据预…

shell 脚本的函数和数组

函数 —— 封装的一个公式&#xff1a;sin、cos、tan —— 函数为脚本的别名 —— 函数就是一个功能模块&#xff0c;在函数中写执行的命令即可&#xff1b;使用函数可以避免代码重复&#xff0c;增加可读性&#xff0c;简化脚本&#xff0c;使用函数可以将大的工程分割为若…

教育数字化转型:塑造未来学习新范式

在国家教育数字化战略行动指引下&#xff0c;我国正积极推动数字化赋能教育高质量发展&#xff0c;以塑造教育发展的新优势。如今&#xff0c;随着科技新基建的普及和数字化赋能教育的深入推进&#xff0c;未来的教育模型正在逐渐形成。 在新的教育模型中&#xff0c;数字化学…

【python海洋专题四十七】风速的风羽图

【python海洋专题四十七】风速的风羽图 图片 往期推荐 图片 【python海洋专题一】查看数据nc文件的属性并输出属性到txt文件 【python海洋专题二】读取水深nc文件并水深地形图 【python海洋专题三】图像修饰之画布和坐标轴 【Python海洋专题四】之水深地图图像修饰 【Pyth…

在一个页面里向两张表里插入内容时,有一些复杂的BUG简单化

向两张表里插入内容时&#xff0c;有一些复杂的BUG简单化 当在第一张表里的页面操作&#xff0c;在第一张表查询结果的页面进行编辑&#xff0c;在编辑的时候需要对第二张表里和第一张表都保存内容&#xff0c;而且插入之后两张表的id关联着&#xff0c;这个时候这张表的id就不…

IntelliJ IDEA 16创建Web项目

首先要理解一个概念&#xff1a;在IntelliJ IDEA中“new Project”相当于eclipse中的工作空间&#xff08;Workspace&#xff09;&#xff0c;而“new Module”相当于eclipse中的工程&#xff08;Project&#xff09;。以下均采用Intellij的说法&#xff0c;请自行对照转换理解…

C语言——从键盘输人一个表示年份的整数,判断该年份是否为闰年,并显示判断结果。

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h> int main() {int year 0;printf("请输入年份&#xff1a;");scanf("%d",&year);if((year%4 0) && (year%100!0) || (year%400 0)){printf("%d是闰年\n",year);}else{p…

Using PeopleCode in Application Engine Programs在应用引擎程序中使用PeopleCode

This section provides an overview of PeopleCode and Application Engine programs and discusses how to: 本节概述了PeopleCode和应用程序引擎程序&#xff0c;并讨论了如何: Decide when to use PeopleCode.决定何时使用PeopleCode。Consider the program environment.考…

队列的实现和OJ练习(c语言)

目录 概念 队列的实现 利用结构体存放队列结构 为什么单链表不使用这种方法&#xff1f; 初始化队列 小提示&#xff1a; 队尾入队列 队头出队列 获取队头元素 获取队尾元素 获取队列中有效元素个数 检测队列是否为空 销毁队列 最终代码 循环队列 队列的OJ题 …

git clone -mirror 和 git clone 的区别

目录 前言两则区别git clone --mirrorgit clone 获取到的文件有什么不同瘦身仓库如何选择结语开源项目 前言 Git是一款强大的版本控制系统&#xff0c;通过Git可以方便地管理代码的版本和协作开发。在使用Git时&#xff0c;常见的操作之一就是通过git clone命令将远程仓库克隆…

SHAP - 机器学习模型可解释性工具

github地址&#xff1a;shap/docs/index.rst at master shap/shap (github.com) SHAP使用文档&#xff1a;欢迎使用 SHAP 文档 — SHAP 最新文档 SHAP介绍 SHAP&#xff08;SHapley Additive exPlanations&#xff09;是一种用于解释预测结果的方法&#xff0c;它基于Shapley…

好的程序员有什么特质呢?

程序员想要提升自己&#xff0c;一定要关注到工作中的方方面面。而一个好的程序员&#xff0c;一般都有这些特质&#xff1a; 弱者抱怨环境&#xff0c;强者改变环境 不要试图通过抱怨环境来获得工作环境上的改变&#xff0c;这不仅不会给你带来任何实质性的改变&#xff0c;…

一文详解Vue生命周期

Vue是一种流行的用于构建用户界面的渐进式JavaScript框架。Vue框架在开发过程中&#xff0c;特别强调对生命周期的理解和管理。通过使用生命周期钩子函数&#xff0c;开发者能够精确地控制Vue实例的创建、挂载、更新以及销毁过程。本文将对Vue的生命周期进行详细的介绍&#xf…
最新文章