【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, 作为该组(合并后的组) 的新right
            else: # 无法合并, (有交集, 或堆为空), 则新区间需单独成组
                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
}

残酷视频

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

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

相关文章

【现代服务端架构】传统服务器 对比 Serverless

在现代开发中&#xff0c;选择合适的架构是至关重要的。两种非常常见的架构模式分别是 传统服务器架构 和 Serverless。它们各有优缺点&#xff0c;适合不同的应用场景。今天&#xff0c;我就带大家一起对比这两种架构&#xff0c;看看它们的差异&#xff0c;并且帮助你选择最适…

数据结构——栈的模拟实现

大家好&#xff0c;今天我要介绍一下数据结构中的一个经典结构——栈。 一&#xff1a;栈的介绍 与顺序表和单链表不同的是&#xff1a; 顺序表和单链表都可以在头部和尾部插入和删除数据&#xff0c;但是栈的结构就锁死了&#xff08;栈的底部是堵死的&#xff09;栈只能从…

Harmony编译与打包

1、hvigor编译脚本文件 hvigorconfig.ts:位于项目根目录,默认不存在(可以自行创建),执行的时机较早,可用于在hvigor生命周期刚开始时操作某些数据。hvigorfile.ts:项目根目录和每个模块目录下都有,在此文件中可以注册插件、任务以及生命周期hook等操作(类似Android的b…

健康的玉米叶病害数据集,玉米识别数据集,对原始图片进行yolov,coco,voc格式标注

健康的玉米叶病害数据集 对原始图片进行yolov&#xff0c;coco&#xff0c;voc格式标注&#xff0c;可识别玉米叶子是否健康 数据集分割 训练组100&#xff05; 442图片 有效集&#xff05; 0图片 测试集&#xff05; 0图片 预处理 自动定向&#xff1a;…

MobileLLM开发安卓AI的体验

MobileLLM是一个在安卓端跑的大语言模型&#xff0c;关键它还有调动api的能力 https://github.com/facebookresearch/MobileLLM 项目地址是这个。 看了下&#xff0c;似乎还是中国人团队 article{liu2024mobilellm, title{MobileLLM: Optimizing Sub-billion Parameter Langua…

IIS部署程序https是访问出现403或ERR_HTTP2_PROTOCOL_ERROR

一、说明 在windows server 2016中的IIS程序池里部署一套系统&#xff0c;通过https访问站点&#xff0c;同时考虑到安全问题以及防攻击等行为&#xff0c;就用上了WAF云盾功能&#xff0c;能有效的抵挡部分攻击&#xff0c;加强网站的安全性和健壮性。 应用系统一直能够正常…

2024小迪安全信息收集第三课

目录 一、Web应用-架构分析-WAF&蜜罐识别 二、Web应用-架构分析-框架组件指纹识别 #Web架构 开源CMS 前端技术 开发语言 框架组件 Web服务器 应用服务器 数据库类型 操作系统信息 应用服务信息 CDN信息 WAF信息 蜜罐信息 其他组件信息 #指纹识别 #WAF识别…

计算机网络技术基础:3.计算机网络的拓扑结构

网络拓扑结构是指用传输媒体互连各种设备的物理布局&#xff0c;即用什么方式把网络中的计算机等设备连接起来。将工作站、服务站等网络设备抽象为点&#xff0c;称为“节点”&#xff1b;将通信线路抽象为线&#xff0c;称为“链路”。由节点和链路构成的抽象结构就是网络拓扑…

【数据结构】基数排序的原理及实现

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在准备26考研 ✈️专栏&#xff1a;数据结构 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 如果文章…

opencv-python的简单练习

一、编程题 读取一张彩色图像并将其转换为灰度图。 import cv2# 读取彩色图像 image_path path_to_your_image.jpg # 替换为你的图像路径 color_image cv2.imread(image_path)# 检查图像是否成功加载 if color_image is None:print("图像加载失败&#xff0c;请检查图…

Python鼠标轨迹算法(游戏防检测)

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

【USB-HID】“自动化键盘“ - 模拟键盘输入

目录 【USB-HID】"自动化键盘" - 模拟键盘输入1. 前言2. 模拟键盘2.1 STM32CubeMX 配置2.2 修改代码配置2.3 发送按键信息 3. 接收主机Setup数据3.1 获取PC下发的数据 4. 总结 【USB-HID】“自动化键盘” - 模拟键盘输入 1. 前言 对于模拟键盘的实现&#xff0c;网…

图-遍历(DFS+BFS)

图-遍历 1.简介2.深度优先遍历dfs3.广度优先遍历bfs4.具体问题4.1 岛屿的最大面积4.2 岛屿的数量 5.总结 1.简介 图是数据结构中的另一种数据结构&#xff0c;通常用来表示多对多的关系。在 C 中&#xff0c;图通常可以通过邻接表或邻接矩阵表示。 例如&#xff1a; 2.深度优…

python中向量指的是什么意思

一、向量是什么 在数学中&#xff0c;向量&#xff08;也称为欧几里得向量、几何向量、矢量&#xff09;&#xff0c;指具有大小&#xff08;magnitude&#xff09;和方向的量。它可以形象化地表示为带箭头的线段。箭头所指&#xff1a;代表向量的方向&#xff1b;线段长度&am…

Vulhub:Log4j[漏洞复现]

CVE-2017-5645(Log4j反序列化) 启动靶场环境 docker-compose up -d 靶机IPV4地址 ifconfig | grep eth0 -A 5 ┌──(root㉿kali)-[/home/kali/Desktop/temp] └─# ifconfig | grep eth0 -A 5 eth0: flags4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 in…

[OpenGL] Transform feedback 介绍以及使用示例

一、简介 本文介绍了 OpenGL 中 Transform Feedback 方法的基本概念和代码示例。 二、Transform Feedback 介绍 1. Transform Feedback 简介 根据 OpenGL-wiki&#xff0c;Transform Feedback 是捕获由顶点处理步骤&#xff08;vertex shader 和 geometry shader&#xff0…

探秘 AI Agent 之 Coze 智能体:从简介到搭建全攻略(4/30)

一、Coze 智能体概述 &#xff08;一&#xff09;Coze 智能体是什么 Coze 智能体是基于机器学习和自然语言处理技术的软件实体&#xff0c;它在人工智能领域扮演着重要的角色&#xff0c;能够像一个智能助手一样&#xff0c;通过与外界环境进行交互学习&#xff0c;进而执行各…

游戏引擎学习第47天

仓库: https://gitee.com/mrxiao_com/2d_game 昨天我们花了一点时间来修复一个问题&#xff0c;但基本上是在修复这个问题的过程中&#xff0c;我们决定添加一个功能&#xff0c;那就是在屏幕上控制多个实体。所以如果我有一个手柄&#xff0c;我可以添加另一个角色&#xff0…

CAPL如何设置或修改CANoe TCP/IP协议栈的底层配置

在CANoe中创建网络节点作为以太网主机时,可以给其配置独立的TCP/IP Stack。 配置的协议栈有一些底层配置参数可以在界面上设置或修改,比如: MTU上图中MTU显示500只是图形界面显示错误,正确值是1500。 TCP延迟确认这些参数也可以通过CAPL动态配置,甚至CAPL还可以配置很多界…

RabbitMQ实现消息发送接收——实战篇(路由模式)

本篇博文将带领大家一起学习rabbitMQ如何进行消息发送接收&#xff0c;我也是在写项目的时候边学边写&#xff0c;有不足的地方希望在评论区留下你的建议&#xff0c;我们一起讨论学习呀~ 需求背景 先说一下我的项目需求背景&#xff0c;社区之间可以进行物资借用&#xff0c…