【LeetCode】2406、将区间分为最少组数

【LeetCode】2406、将区间分为最少组数

文章目录

  • 一、数据结构-堆、贪心
    • 1.1 数据结构-堆、贪心
    • 1.2 多语言解法
  • 二、扫描线
    • 2.1 扫描线

一、数据结构-堆、贪心

1.1 数据结构-堆、贪心

题目已知一些区间, 需要尽量合并, 使 组 最少.

可以用图解画一下

  1. 因为尽量合并, 为了紧凑, 尽量按 left 从小到大 依次处理. 而题目答案也和顺序无关(因为只需要组的数目), 所以可以排序.

  2. 以示例一为例, 如果已经有 [1, 5] 的情况下, [1, 10] 因为和 [1, 5] 有交集所以必须单独成组. 则分为两个组, 如下

  3. 接下来, 再放 [2, 3], 其实 [2, 3] 也和 [1, 5] 重叠 (核心是 [2, 3] 的左端点2, 小于 [1, 5] 的右端点 5), 所以无法和 [1, 5] 合并, 而必须单独成组, 如下:

  4. 接下来, 再放 [5, 10], 其实只需要考虑已有各组的最小的 右端点(即 [2, 3] 的 3 是最小的), 而 [5, 10] 和 [2, 3] 并不相交, 所以可以合并

  5. 接下来, 再放 [6, 8], 此时最小的右端点的组为 [1, 5], 而 [6, 8] 和 [1, 5] 并不相交, 所以可以合并为一个组, 如下:

通过推导, 可总结出

  1. 如果新区间 可 和 右端点最小的组 合并, 则是最紧凑的, 则应合并尽量合并, 并更新 “右端点最小的组的 新右端点” 这是贪心的思想.
  2. 否则, 新区间 应 单独成组.

而如何快速找到 “右端点最小的组”, 且更新 “右端点最小的组的 新右端点” 呢? => 堆 => 最小堆维护各组的右端点即可

所以伪代码如下:

  1. 按左端点, 排序各区间
  2. 准备一个堆(其中放的是各组的 right), 遍历各区间
    2.1 若 “新区间的 left” > “right最小的组的 right”, 则意味着可合并二者, 则把堆顶替换为 “新区间的 right” 并 heapify 调整堆
    2.2 若 “新区间的 left” <= “right最小的组的 right” 或 堆为空, 则需单独成组
  3. 最终 堆的大小 即为组的个数, 即为答案
// go
func minGroups(intervals [][]int) int {sort.Slice(intervals, func(i, j int) bool {return intervals[i][0] < intervals[j][0] // 按左端点排序})h := hp{}for _, p := range intervals {left, right := p[0], p[1]if h.Len() > 0 && left > h.IntSlice[0] {h.IntSlice[0] = right // 把新区间的right, 放入堆顶heap.Fix(&h, 0) // heapify 堆顶 (第0下标的就是堆顶)} else {heap.Push(&h, right)}}return h.Len()
}type hp struct {sort.IntSlice}
func (h *hp) Push(v any) {h.IntSlice = append(h.IntSlice, v.(int))}
func (h *hp) Pop() any {a := h.IntSlice; v := a[len(a)-1]; h.IntSlice = a[:len(a)-1]; return v}

灵神视频
灵神题解

1.2 多语言解法

C p p / G o / P y t h o n / R u s t / J s / T s Cpp/Go/Python/Rust/Js/Ts Cpp/Go/Python/Rust/Js/Ts

// cpp
// go 同上
# python
class Solution:def minGroups(self, intervals: List[List[int]]) -> int:intervals.sort()h = []for left, right in intervals: # [[l1, r1], [l2, r2], [l3, r3]]if h and left > h[0]: # 可合并 新区间[l,r] 和 老组, 其中 h[0] 是堆顶(表示 最小right的组 的right)heapreplace(h, right) # 把新区间的right, 作为该组(合并后的组) 的新rightelse: # 无法合并, (有交集, 或堆为空), 则新区间需单独成组heappush(h, right)return len(h)
// rust
// js
// ts

二、扫描线

2.1 扫描线

题目本质是问, 同一时刻, 最多有几个组 (和253题: 同一时刻最多几个会议室 是同样的模板)
可以用差分数组, 记录 会议的变化(增加或减少会议)


如上图所示:
1时刻增加二个会议室 (因[1, 5] 增加一个, 因 [1, 10] 增加一个)
2时刻增加一个会议室 (因[2, 3] 增加一个)
3时刻减少一个会议室 (因[2, 3] 减少一个)
5时刻增加一个会议室 (因 [5, 10] 增加一个)
5时刻减少一个会议室 (因 [1, 5] 减少一个)
6时刻增加一个会议室 (因 [6, 8] 增加一个)
8时刻减少一个会议室 (因 [6, 8] 减少一个)

注意边界条件为5时刻, 虽然同时增加且减少一个, 但还是不能相互抵消, 即如下图需要先从2增加到3再减少回2. 毕竟此时刻两个会议室都需要被占用(因为前一个会议室还没有结束嘛)
![]](https://i-blog.csdnimg.cn/direct/b57cde44df3d4566bd769978433e3017.png)
所以为了处理这种边界条件, 可视为 [left, right] 的闭区间为 [left, right+1] 的闭区间, 即视为 right +1 会议才结束

func minGroups(intervals [][]int) (ans int) {diff := map[int]int{}for _, p := range intervals {left, right := p[0], p[1]diff[left]++diff[right+1]--}// ds 排序, 从而方便从小到大遍历keys := []int{}for k := range diff { keys = append(keys, k) } // 收集的是下标slices.Sort(keys)sum := 0 // 差分数组, 求前缀和, 得到的当前时刻的会议室数目for _, k := range keys {sum += diff[k] // 通过k找到对应的会议室数目 diff[k]ans = max(ans, sum) // d 为会议室的变化, sum 为 会议室的数目, ans 为最多的会议室数目}return ans
}

残酷视频

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

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

相关文章

彻底理解如何优化接口性能

作为后端研发&#xff0c;必须要掌握怎么优化接口的性能或者说是响应时间&#xff0c;这样才能提高系统的系能&#xff0c;本文通过如下两个方面进行分析&#xff1a; 一.后端代码 有如下几步&#xff1a; 1.缓存机制 这是最场景的方式&#xff0c;当使用了缓存后&#xff0c;…

Java性能调优 - JVM性能监测及调优

JVM 内存模型概述 堆 堆是JVM内存中最大的一块内存空间&#xff0c;该内存被所有线程共享&#xff0c;几乎所有对象和数组都被分配到了堆内存中。堆被划分为新生代和老年代&#xff0c;新生代又被进一步划分为Eden和Survivor区&#xff0c;最后Survivor由From Survivor和To Su…

【计算机网络】期末考试预习复习|上

作业讲解 物理层作业 共有4个用户进行CDMA通信。这4个用户的码片序列为&#xff1a; A: (–1 –1 –1 1 1 –1 1 1)&#xff1b;B: (–1 –1 1 –1 1 1 1 –1) C: (–1 1 –1 1 1 1 –1 –1)&#xff1b;D: (–1 1 –1 –1 –1 –1 1 –1) 现收到码片序列&#xff1a;(–1 1 –…

Element plus 下拉框组件选中一个选项后显示的是 value 而不是 label

最近刚进行 Vue3 Element plus 项目实践&#xff0c;在进行表单二次封装的时候&#xff0c;表单元素 select 下拉框组件选中一个选项后显示的是 value 而不是 label&#xff0c;下面上代码&#xff1a; 原来的写法&#xff1a; <el-selectv-if"v.type select"…

SpringBoot2+Vue2开发工作管理系统

项目介绍 在工作中使用的管理系统&#xff0c;可以随手记录一些笔记、可以汇总一些常用网站的链接、可以管理自己负责的项目、可以记录每日日报和查看历史日报、可以记录加班情况、可以记录报销内容、可以编写文章文档。 系统功能 我的笔记快捷入口项目管理今日日报我的日报…

C语言实现八大排序算法

目录 1.插入排序 1.1 直接插入排序 1.2 希尔排序 2. 选择排序 2.1 直接选择排序 2.2 堆排序 *TopK问题&#xff1a; 3. 交换排序 3.1 冒泡排序 3.2 快速排序 1. Hoare版本 2. 挖坑法 3. 前后指针法 4. 快速排序优化 5. 非递归快速排序 4.归并排序 1.递归式归并…

SpringCloudAlibaba | Sentinel从基础到进阶

一、Sentinel简介 Sentinel是SpringCloudAlibaba的一个组件&#xff0c;主要用于解决微服务架构中的高可用性和稳定性问题&#xff08;雪崩问题&#xff09;。 常见的使用场景有&#xff1a; 流量控制舱壁模式&#xff08;线程隔离&#xff09;超时处理熔断降级 二、流量控…

51c嵌入式~单片机~合集3

我自己的原文哦~ https://blog.51cto.com/whaosoft/12362395 一、STM32代码远程升级之IAP编程 IAP是什么 有时项目上需要远程升级单片机程序&#xff0c;此时需要接触到IAP编程。 IAP即为In Application Programming&#xff0c;解释为在应用中编程&#xff0c;用户自己的…

Spring Boot 集成 Elasticsearch怎样在不启动es的情况下正常启动服务

解释 在spingboot 集成es客户端后&#xff0c;每当服务启动时&#xff0c;服务默认都会查看es中是否已经创建了对应的索引&#xff0c;如果没有索引则创建。基于上面的规则我们可以通过配置不自动创建索引来达到在没有es服务的情况下正常启动服务。 解决办法 在entity类的Docu…

Linux在Ubuntu系统下安装MySQL数据库(全网最详细)

1.在ubuntu下安装MySQL数据库 第一步要先&#xff1a;切换到root用户 以我自己的为例&#xff08;自行输入密码&#xff09; ljwVM-16-16-ubuntu:~$ su - 1.1 查看操作系统版本 rootVM-16-16-ubuntu:~# lsb_release -a 1.2 添加MySQL APT源 1.2.1 访问下载⻚⾯并下载发布包…

vs code 2024编译环境问题记录

之前vs code环境配置了好一会&#xff0c;现在将遇到的问题记录一下&#xff0c;并贴上解决方法。 在这之前&#xff0c;关键的gcc编译器竟然在Python生成exe的过程中不小心下载了Mingw64&#xff0c;然后导致gcc编译器已经安装好在某个目录下了 命令行查看发现&#xff0c;原…

linux网络编程 | c | epoll实现IO多路转接服务器

epoll实现IO多路转接服务器 可通过以下视频学习 06-opell函数实现的多路IO转接_哔哩哔哩_bilibili 通过响应式–多路IO转接实现 文章目录 epoll实现IO多路转接服务器1.思路&功能核心思路 2.代码实现multi_epoll_sever.c运行图 1.思路&功能 **功能&#xff1a;**客…

植物大战僵尸辅助【控制台版本】

前面介绍了使用CE和OD的简单使用&#xff1a;CE和OD介绍和使用CE查找阳光的教学&#xff1a;阳光基地址和偏移地址&#xff0c;下面先使用最简单的控制台程序来实现修改阳光的功能。 项目地址 1.分析程序 我们的控制台程序想要修改植物大战僵尸游戏内的数据&#xff0c;它们…

elasticsearch 使用Painless脚本

文章目录 1. 创建索引2. 插入模拟数据Painless 脚本的基本特点&#xff1a;Painless 脚本的常见用途1. 脚本查询和过滤示例&#xff1a;基于脚本的查询 2. 脚本字段示例&#xff1a;脚本字段 3. 聚合中的脚本示例&#xff1a;脚本聚合 4. 文档更新中的脚本示例&#xff1a;文档…

【Elasticsearch】高亮搜索:从原理到Web呈现

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

15.初始接口1.0 C#

这是一个用于实验接口的代码 适合初认识接口的人 【CSDN开头介绍】&#xff08;文心一言AI生成&#xff09; 在C#编程世界中&#xff0c;接口&#xff08;Interface&#xff09;扮演着至关重要的角色&#xff0c;它定义了一组方法&#xff0c;但不提供这些方法的实现。接口作为…

Day9 神经网络的偏导数基础

多变量函数与神经网络 在神经网络中&#xff0c;我们经常遇到多变量函数。这些函数通常描述了网络的输入、权重、偏置与输出之间的关系。例如&#xff0c;一个简单的神经元输出可以表示为&#xff1a; z f ( w 1 x 1 w 2 x 2 … w n x n b ) z f(w_1x_1 w_2x_2 \ldots…

map和set题目练习

一、习题一&#xff1a;随机链表的复制 1.1题目详情 1.2思路 在没有学习map和set之前&#xff0c;解决这道题最大的问题就在于无法建立原链表与拷贝链表的映射关系&#xff0c;只能通过在原链表每个节点后面新建一个新的链表来进行节点间的对应&#xff0c;而学习了map之后&a…

C语言入门(一):A + B _ 基础输入输出

前言 本专栏记录C语言入门100例&#xff0c;这是第&#xff08;一&#xff09;例。 目录 一、【例题1】 1、题目描述 2、代码详解 二、【例题2】 1、题目描述 2、代码详解 三、【例题3】 1、题目描述 2、代码详解 四、【例题4】 1、题目描述 2、代码详解 一、【例…

渗透测试学习笔记(五)网络

一.IP地址 1. IP地址详解 ip地址是唯一标识&#xff0c;一段网络编码局域网&#xff08;内网&#xff09;&#xff1a;交换机-网线-pcx.x.x.x 32位置2进制&#xff08;0-255&#xff09; IP地址五大类 IP类型IP范围A类0.0.0.0 到 127.255.255.255B类128.0.0.0 到191.255.25…