AcWing 908

news/2025/11/22 23:37:24/文章来源:https://www.cnblogs.com/clarencezzh/p/19258906

AcWing 908. 最大不相交区间数量

一、题目描述

给定 ( N ) 个闭区间 ([a_i, b_i]),请你在数轴上选择若干区间,使得选中的区间之间互不相交(包括端点)。输出可选取区间的最大数量。

输入格式

第一行包含整数 ( N ),表示区间数。
接下来 ( N ) 行,每行包含两个整数 ( a_i, b_i ),表示一个区间的两个端点。

输出格式

输出一个整数,表示可选取区间的最大数量。

数据范围

( 1 \leq N \leq 10^5 ),( -10^9 \leq a_i \leq b_i \leq 10^9 )

输入样例

3
-1 1
2 4
3 5

输出样例

2

二、解题思路

核心发现:与「区间选点」同源

这道题的解法和 AcWing 905. 区间选点 完全一致。两道题本质都是通过贪心策略最大化区间利用率,只是问题描述角度不同:

  • 区间选点:求最少点数覆盖所有区间;
  • 最大不相交区间:求最多不重叠区间数量。
    两者的最优解思路完全互通,核心都是「按右端点排序 + 贪心选择」。

贪心策略

  1. 按右端点排序:将所有区间按右端点从小到大排序。这样做的目的是,每次选择区间时,尽可能保留数轴上的剩余空间,以容纳更多后续区间。
  2. 筛选不相交区间
    • 初始化最后选中区间的结束边界 ed 为极小值(如负无穷),结果计数 res 为 0。
    • 遍历排序后的区间:
      • 若当前区间的左端点 > ed,说明该区间与之前选中的区间不相交,选择该区间,res 加 1,同时更新 ed 为当前区间的右端点。
      • 若当前区间与之前选中的区间重叠(包括端点),则跳过该区间,避免冲突。

为什么这样有效?

按右端点排序后,每次选中的区间都是当前能找到的「最早结束」的区间。这种选择能最大限度地留出后续空间,让更多区间有机会被选中,从而达到「最大不相交数量」的目标。

例如样例中排序后区间为 ([-1,1])、([2,4])、([3,5]):

  • 选中 ([-1,1]),ed=1
  • 下一个区间 ([2,4]) 的左端点 2 > 1,选中,res=2ed=4
  • 最后一个区间 ([3,5]) 与 ([2,4]) 重叠,跳过;
  • 最终结果为 2,与样例输出一致。

三、Java 代码实现

import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int[][] intervals = new int[n][2];for (int i = 0; i < n; i++) {intervals[i][0] = sc.nextInt(); // 区间左端点intervals[i][1] = sc.nextInt(); // 区间右端点}sc.close();// 按区间右端点从小到大排序Arrays.sort(intervals, new Comparator<int[]>() {@Overridepublic int compare(int[] a, int[] b) {return a[1] - b[1];}});int res = 0;int ed = Integer.MIN_VALUE; // 初始结束边界设为极小值for (int[] interval : intervals) {int l = interval[0];int r = interval[1];// 若当前区间左端点 > 上一个选中区间的右端点,说明不相交if (l > ed) {res++;ed = r; // 更新结束边界为当前区间右端点}}System.out.println(res);}
}

代码说明

  1. 输入处理:使用二维数组存储区间,通过 Scanner 读取输入数据。
  2. 排序逻辑:利用 Arrays.sort 结合自定义比较器,按区间右端点升序排序。
  3. 贪心筛选:遍历排序后的区间,筛选出不相交的区间并计数,最终输出结果。
  4. 时间复杂度:( O(n \log n) ),核心开销在排序(( n ) 为区间数量),遍历过程仅需 ( O(n) )。
  5. 空间复杂度:( O(\log n) ),排序所需的递归栈空间(Java 内置排序为双轴快排)。

四、注意事项

  1. 边界处理:初始 ed 设为 Integer.MIN_VALUE,确保第一个区间一定能被选中。
  2. 排序稳定性:按右端点排序时,若两个区间右端点相同,左端点顺序不影响结果,无需额外处理。
  3. 数据规模适配:代码采用二维数组存储,避免自定义类的额外开销,适配 ( 10^5 ) 级别的数据规模。

五、总结

这道题的核心是发现其与「区间选点」的同源性,掌握「按右端点排序 + 贪心选择」的模板后,可快速解决。贪心算法的关键在于找到「局部最优解」并推导出「全局最优解」,本题中「选择最早结束的区间」就是局部最优,最终实现全局最大不相交数量。

这类区间贪心问题的通用思路可总结为:

  1. 排序(按左端点或右端点,根据问题场景选择);
  2. 遍历筛选(按贪心策略选择区间或点)。

掌握该模板后,可轻松应对「区间覆盖」「区间选点」「最大不相交区间」等同类问题。

LeetCode 435. 无重叠区间

一、题目描述

给定一个区间集合 intervals,其中 intervals[i] = [start_i, end_i],返回需要移除区间的最小数量,使剩余区间互不重叠。注意:仅在端点接触的区间不算重叠(如 [1,2][2,3] 不重叠)。

示例

  • 示例 1:
    输入:intervals = [[1,2],[2,3],[3,4],[1,3]]
    输出:1
    解释:移除 [1,3] 后,剩余区间无重叠。
  • 示例 2:
    输入:intervals = [[1,2],[1,2],[1,2]]
    输出:2
    解释:需移除两个 [1,2],仅剩一个区间无重叠。
  • 示例 3:
    输入:intervals = [[1,2],[2,3]]
    输出:0
    解释:区间已无重叠,无需移除。

提示

  • 1 <= intervals.length <= 10^5
  • intervals[i].length == 2
  • -5 * 10^4 <= start_i < end_i <= 5 * 10^4

二、解题思路

核心转化:最小移除数 = 总区间数 - 最大不相交区间数

这道题的本质的是求「最大不相交区间数量」—— 因为要移除的区间最少,就意味着要保留的不相交区间最多。两者关系为:
需要移除的区间数 = 总区间数 - 最大不相交区间数

贪心策略(与「最大不相交区间」一致)

  1. 按右端点排序:将所有区间按右端点升序排序。这样做能让每次选择的区间尽可能早地结束,留出更多空间容纳后续区间,从而最大化不相交区间的数量。
  2. 筛选不相交区间
    • 初始化最后保留区间的结束边界 lastEnd 为极小值,最大不相交区间数 maxNonOverlap 为 0。
    • 遍历排序后的区间:
      • 若当前区间的左端点 >= lastEnd(无重叠),则保留该区间,maxNonOverlap 加 1,更新 lastEnd 为当前区间的右端点。
      • 若重叠,则跳过该区间(后续需移除)。

逻辑验证(以示例 1 为例)

示例 1 输入:[[1,2],[2,3],[3,4],[1,3]]
排序后区间:[[1,2],[1,3],[2,3],[3,4]]

  • 保留 [1,2]lastEnd=2maxNonOverlap=1
  • 区间 [1,3][1,2] 重叠,跳过;
  • 区间 [2,3] 的左端点 2 >= 2,保留,lastEnd=3maxNonOverlap=2
  • 区间 [3,4] 的左端点 3 >= 3,保留,maxNonOverlap=3
    总区间数 4 - 最大不相交数 3 = 1,与示例输出一致。

三、Java 代码实现

import java.util.Arrays;
import java.util.Comparator;class Solution {public int eraseOverlapIntervals(int[][] intervals) {if (intervals == null || intervals.length == 0) {return 0;}// 按区间右端点升序排序Arrays.sort(intervals, new Comparator<int[]>() {@Overridepublic int compare(int[] a, int[] b) {return a[1] - b[1];}});int n = intervals.length;int maxNonOverlap = 1; // 至少有一个不相交区间int lastEnd = intervals[0][1]; // 第一个区间的右端点for (int i = 1; i < n; i++) {int currentStart = intervals[i][0];// 无重叠时保留当前区间if (currentStart >= lastEnd) {maxNonOverlap++;lastEnd = intervals[i][1];}}// 最小移除数 = 总区间数 - 最大不相交区间数return n - maxNonOverlap;}// 测试代码public static void main(String[] args) {Solution solution = new Solution();int[][] intervals1 = {{1,2},{2,3},{3,4},{1,3}};System.out.println(solution.eraseOverlapIntervals(intervals1)); // 输出 1int[][] intervals2 = {{1,2},{1,2},{1,2}};System.out.println(solution.eraseOverlapIntervals(intervals2)); // 输出 2int[][] intervals3 = {{1,2},{2,3}};System.out.println(solution.eraseOverlapIntervals(intervals3)); // 输出 0}
}

代码说明

  1. 排序优化:按右端点排序是核心,确保每次保留的区间最早结束,最大化后续容纳空间。
  2. 边界处理:空输入直接返回 0,避免异常。
  3. 时间复杂度O(n log n),排序占主要开销,遍历仅 O(n),适配 10^5 级数据。
  4. 空间复杂度O(log n),排序所需递归栈空间(Java 内置排序为双轴快排)。

四、注意事项

  1. 区间端点判定:题目明确「仅端点接触不算重叠」,因此判断条件为 currentStart >= lastEnd(而非 >)。
  2. 排序避免溢出:本题区间端点范围较小(-5e4 ~ 5e4),用 a[1]-b[1] 比较可行;若端点范围更大(如 2^31-1),需改用 Integer.compare(a[1], b[1]) 避免溢出。
  3. 与同类题关联:本题与「最大不相交区间数量」「用最少箭引爆气球」思路完全同源,均为「按右端点排序 + 贪心筛选」,可统一记忆模板。

五、总结

这道题的关键是将「最小移除区间数」转化为「最大不相交区间数」,再用成熟的贪心模板求解。贪心算法的核心是找到「局部最优解」(每次选最早结束的区间),最终推导「全局最优解」(最多不相交区间)。

掌握这类区间贪心问题的通用模板:

  1. 排序(按右端点或左端点,优先右端点最大化后续空间);
  2. 遍历筛选(按重叠条件保留区间,统计最优解);
  3. 转化问题(如本题将「移除数」转化为「保留数」的差值)。

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

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

相关文章

2025最新园林景观品牌品质推荐——至大园林景观,设计、施工、绿化,三维服务筑造精品,

随着城市更新战略的深入推进与人们对美好生活空间需求的提升,园林景观行业迎来高质量发展机遇。在2025年的行业竞争中,上海至大园林景观工程有限公司(简称“至大园林景观”)凭借“设计引领、施工保障、养护托底”的…

2025/11/22 NOIP 模拟赛小记

\(100+100+28+40=268\),T3 好像拿的分过于少了。 不管了,T1、T2 都击杀了,还行。 T1 原题:TopCoder 13061。题意 有 \(n\) 种面值的硬币,第 \(i\) 种面值为 \(a_i\),保证 \(a_1=1\),\(\forall 1\leq i<n,a_i…

icmp for linux

在 Linux 系统中,ping 命令是用于测试网络连通性的一种工具,它使用的是 ICMP(Internet Control Message Protocol) 协议。ping 命令可以用来检查本地主机与远程主机之间的网络连接是否正常。一、ping 命令的基本用…

iceberg sql能查啥

Iceberg SQL 是一个用于查询 Apache Iceberg 表的 SQL 查询引擎。Apache Iceberg 是一个开源项目,它为大数据处理提供了一个表格式和一组处理工具。Iceberg 的主要特点包括支持 ACID 事务、高效的元数据处理、支持复杂…

iceberg sql能实现啥

Apache Iceberg是一个开源表格式,旨在解决大数据分析中的数据存储和管理挑战。它通过提供高性能的表格式、ACID事务支持、模式演化、分区演化等功能,使得数据湖更加灵活和高效。以下是Iceberg SQL的主要功能:高性能…

iceberg sql能做什么

Apache Iceberg是一个开源的数据表格格式和查询引擎,旨在提供更强大的数据管理和分析功能。它支持ACID事务操作、数据版本控制、架构演化、跨平台兼容性、数据分层和分区、兼容现有工具和生态系统等功能。以下是Icebe…

南昌航空大学-软件学院-余思莹-第一次blog作业

目录一、前言二、设计与分析2.1 OOP1-NCHU_单部电梯调度程序2.1.1 题目2.1.2 设计与分析2.2 OOP2-NCHU_单部电梯调度程序2.2.1 题目2.2.2 设计与分析2.3 OOP3-NCHU_单部电梯调度程序2.3.1 题目2.3.2 设计与分析三、踩坑…

java电梯调度三次作业总结

前言: 本次PTA的单部电梯调度程序设计分为三次迭代完成,因此,第一次作业的实现质量对整个项目至关重要,初期最大的挑战在于理解电梯的运行逻辑,本题采用的LOOK算法变种与日常生活中常见的电梯运行方式有所不同,在…

[数据压缩] LZ4 压缩算法

0 序续接: [数据压缩/数据归档] 压缩算法综述 - 博客园/千千寰宇,展开研究 LZ4 压缩算法与压缩格式。1 概述: LZ4 压缩算法LZ4 是一种无损数据压缩算法,专注于极致的压缩和解压速度,同时保持合理的压缩比。它由 Ya…

什么是oracle的for engineered system版本

今天想着看看Oracle最新26ai的版本,奈何官网没有企业版,最新还是21c,于是去edelivery找。只发现了23.5,也行,算很新了,但是发现了个for engineered system版,没有看到企业版。如下:经查,for Engineered Syste…

CAN通信数据帧与远程帧,标准格式与远程格式的区分

礼貌借图,这是B站up主TrojanGeneric发布视频里他自己总结的对比。 在学习概念的时候确实被这里混乱的编码规则给硬控了一下,我的学习资料中关于每一位含义的介绍似乎有些问题。通过与 AI 的交互,感觉自己对这里清晰…

NumPy 从零开始:轻松掌握 Python 科学计算的“魔法”

NumPy 从零开始:轻松掌握 Python 科学计算的“魔法”你是否曾为处理大量数据而烦恼? 用 Python 写循环计算 100 万条数据,结果等了 5 分钟? 用 NumPy,同样的计算 5 秒搞定! 这不是魔法,是 NumPy 的“向量化”魔…

Windows 内网部署共享Neko浏览器

外网电脑 1.下载安装Docker 官网:https://docs.docker.com/desktop/install/windows-install/2.拉取 Neko 的 Chrome 浏览器镜像 docker pull docker.m.daocloud.io/m1k1o/neko:google-chrome3.将拉取的镜像导出为.ta…

iceberg sql怎样运用

Iceberg SQL 是一个用于处理 Apache Iceberg 表的 SQL 查询接口。Apache Iceberg 是一个开源项目,它为大数据处理提供了一个统一的数据格式和数据管理工具。Iceberg 提供了高效的元数据处理能力,支持 ACID 事务,并且…

Premium Multidiag TCS CDP+ V2021: Car Truck Diagnostic Tool with Bluetooth + Free Keygen

The Diagnostic Challenge: Pain Points for Mechanics and Car Owners In the world of automotive repair, time is money—and frustration often arises from outdated tools, limited compatibility, and the str…

iceberg sql怎样使用

Iceberg SQL 是一个用于与 Apache Iceberg 交互的接口。Apache Iceberg 是一个开源项目,提供了一种存储和处理大数据集的方法,特别适用于 Spark、Presto 和 Trino 等大数据处理引擎。以下是使用 Iceberg SQL 的一些基…

iceberg sql怎样优化

Iceberg SQL 优化可以从多个方面进行,以下是一些建议:使用合适的文件格式:Iceberg 支持多种文件格式,如 Parquet、ORC 等。选择合适的文件格式可以提高查询性能。例如,Parquet 格式支持列式存储和压缩,可以有效地…

oracle的free版是什么版本?

许久不见,oracle官网下载现在多了个free版,而且是默认下载选项,经查相关信息,现在的oracle free版就是以前的oracle xe,并非企业版、标准版的开发者版本。 Oracle 23c Free is the replacement for what would ha…

`squares_np = x * x` 是不是向量的叉乘?

这三个问题核心围绕「NumPy 数组运算的本质」「* 与 ** 的区别」「向量叉乘的定义」,下面用通俗+严谨的方式逐一解答,结合代码示例帮你彻底理清: 一、squares_np = x * x 可以改成 squares_np = x ** 2 吗? 完全可…

AcWing 905. 区间选点

AcWing 905. 区间选点 一、题目描述 给定 ( N ) 个闭区间 ([a_i, b_i]),请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。 输出选择的点的最小数量。 位于区间端点上的点也算作区间内。 输入格式 第…