跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
编程语言java算法

632. 最小区间 - 贪心算法思路与实现

讲解 LeetCode 第 632 题最小区间的解法。问题要求在 k 个非递减整数列表中找出一个最小区间,使得每个列表至少有一个数在该区间内。核心思路采用贪心算法,维护一个包含各列表当前最小元素的集合,通过不断移除集合中的最小值并替换为对应列表的下一个元素来压缩区间范围,同时记录最优解。文中提供了 C++ 和 Java 两种语言的完整实现代码。

t ag发布于 2026/3/27更新于 2026/9/168 浏览

632. 最小区间

你有 k 个非递减排列的整数列表。找到一个最小区间,使得 k 个列表中的每个列表至少有一个数包含在其中。

我们定义如果 b-a < d-c 或者在 b-a == d-c 时 a < c,则区间 [a,b] 比 [c,d] 小。

示例

示例 1:

输入:nums = [[4,10,15,24,26], [0,9,12,20], [5,18,22,30]] 输出:[20,24] 解释:列表 1:[4, 10, 15, 24, 26],24 在区间 [20,24] 中。列表 2:[0, 9, 12, 20],20 在区间 [20,24] 中。列表 3:[5, 18, 22, 30],22 在区间 [20,24] 中。

示例 2:

输入:nums = [[1,2,3],[1,2,3],[1,2,3]] 输出:[1,1]

提示

  • nums.length == k
  • 1 <= k <= 3500
  • 1 <= nums[i].length <= 50
  • -10^5 <= nums[i][j] <= 10^5
  • nums[i] 按非递减顺序排列

思路

题目要求给出若干个非递减序列,算出一个区间 [l,r],使得每个序列至少有一个数在区间内。

既然题目要求每个序列中至少有一个数在区间内,那么索性先选取各个序列中最小的数也就是各个序列的首元素构成一个集合,此时,集合内的数就会生成一个区间 [l1,r1],l1 就是所有序列首元素的最小值,r1 就是首元素的最大值。这时候的区间一定满足'每个序列至少有一个数在区间内'的条件,但未必是最小的,之后就要压缩区间。

在压缩区间之前必须明确,在 [l1,r1] 与初始集合的基础上进行压缩,集合内必须保证含有每个序列中的数。而怎么压缩区间就体现了贪心的思想,每次压缩都从集合中弹出最小的数,之后,为了满足'每个序列至少有一个数在区间内'的条件,需要在其所属序列中选择下一个数加入集合,获取新集合的区间对比更新所求区间。

例如:当前从集合中弹出的元素是 nums[i][j],那么就需要将 nums[i][j+1] 加入集合,假设弹出前集合的区间为 [l1,r1],l1 为集合中最小元素,r1 为集合中最大元素,[l1,r1] 为当前压缩到的最小区间,即 ans 区间;加入元素后的新集合对应的新区间为 [l2,r2],此时就要将 ans 与新区间进行对比,如果新区间小于 ans,就更新 ans 为新区间,否则 ans 不动。

为什么每次弹出集合中最小的数,加入其序列中的下一个数?

答:因为题目保证所有序列都为非递减序列,则每次弹出集合中最小的数(也就是 l1),并加入其原序列的下一个数 x,那么 x 一定大于 l1。如果,此时 x 为新集合中最小的数,那么新集合的新区间为 [x,r1] 的长度一定小于原区间长度,又因为 x 是从 l1 的序列中加入集合的,说明弹出、加入的过程不会影响到集合中其他序列的数,也就是一定不会破坏'每个序列至少有一个数在区间内'的条件,所以 [x,r1] 一定是当前满足题意的最小区间,随之更新 ans,从而达到压缩区间的目的;如果此时 x 不为新集合中最小的数,最小的数为 l2,x 可能大于 r1,也可能在 [l2,r1] 之间,此时就要对比新集合的新区间与 ans 的大小,判断是否更新 ans 同样可以压缩区间。即使某个序列中有多个数在区间也无所谓,只要满足'每个序列至少有一个数在区间内'的条件即可。

至此,不断弹出,加入元素,保证集合内元素个数不变,不断在贪心的基础上压缩,直到集合不可再压缩,返回 ans 区间。

代码实现

C++ 实现

class Solution {
public:
    typedef struct node{
        int data;//当前元素数据
        int i;//原序列位置
        int idx;//所在原序列下标
          < ( node& a) {
             (data == a.data) {
                 i < a.i;
            }
             data < a.data;
        }
    }Node;

    {
        vector<> ans;
         (nums.()) {
             ans;
        }
        set<Node> s;
         ( i = ; i < nums.(); i++) {
            
             (nums[i].()) {
                ;
            }
            Node t = { nums[i][],i, };
            s.(t);
        }
         (s.()) {
             ans;
        }
         l = (*s.()).data;
         r = (*s.()).data;
        
         () {
             it = s.();
             i = (*it).i;
             idx = (*it).idx;
             (idx == nums[i].() - ) {
                
                ;
            }  {
                s.(s.());
                Node t = { nums[i][idx + ],i,idx +  };
                s.(t);
                 (((*s.()).data - (*s.()).data) < (r - l)) {
                    
                    r = (*s.()).data;
                    l = (*s.()).data;
                }   (((*s.()).data - (*s.()).data) == (r - l)) {
                    
                     ((*s.()).data < l) {
                        r = (*s.()).data;
                        l = (*s.()).data;
                    }
                }
            }
        }
        ans.(l);
        ans.(r);
         ans;
    }
};
bool
operator
const
const
if
return
return
vector<int> smallestRange(vector<vector<int>>& nums)
int
if
empty
return
for
int
0
size
//初始化集合,将每个序列最小数加入集合
if
empty
continue
0
0
insert
if
empty
return
int
begin
int
rbegin
//压缩区间
while
1
auto
begin
int
int
if
size
1
//最小元素弹出后无法再加入元素
break
//跳出循环,压缩结束
else
erase
begin
1
1
insert
if
rbegin
begin
//遇到更小的区间,更新
rbegin
begin
else
if
rbegin
begin
//同样长度的区间选择字典序更小的,更新
if
begin
rbegin
begin
push_back
push_back
return

Java 实现

class Solution {
    public class Node implements Comparable<Node> {
        int data;
        int i;
        int idx;
        public Node(int data, int i, int idx) {
            this.data = data;
            this.i = i;
            this.idx = idx;
        }
        public int compareTo(Node a){
            if(this.data==a.data){
                return this.i-a.i;
            }
            return this.data-a.data;
        }
    }

    public int[] smallestRange(List<List<Integer>> nums) {
        int ans[]=new int[2];
        if(nums.size()==0){
            return ans;
        }
        TreeSet<Node> s=new TreeSet<>();
        for (int i = 0; i < nums.size(); i++) {
            if(nums.get(i).size()==0){
                continue;
            }
            Node t=new Node(nums.get(i).get(0),i,0);
            s.add(t);
        }
        if(s.size()==0){
            return ans;
        }
        int l=s.first().data;
        int r=s.last().data;
        while(true){
            Node it=s.first();
            int i=it.i;
            int idx=it.idx;
            if(idx==nums.get(i).size()-1){
                break;
            } else{
                s.remove(s.first());
                Node t=new Node(nums.get(i).get(idx+1),i,idx+1);
                s.add(t);
                int len=s.last().data-s.first().data+1;
                if(len<(r-l+1)){
                    l=s.first().data;
                    r=s.last().data;
                } else if(len==(r-l+1)){
                    if(l>s.getFirst().data){
                        l=s.first().data;
                        r=s.last().data;
                    }
                }
            }
        }
        ans[0]=l;
        ans[1]=r;
        return ans;
    }
}

目录

  1. 632. 最小区间
  2. 示例
  3. 提示
  4. 思路
  5. 代码实现
  6. C++ 实现
  7. Java 实现

更多推荐文章

查看全部
  • C++ 哈希结构进阶:位图与布隆过滤器详解
  • LTX-2.3:开源 AI 视频生成新标杆,支持音视频同步生成
  • C++26 反射驱动类型检查重塑代码质量
  • 基于 Llama-Factory 的盘古大模型轻量化训练方案
  • 2024 年 AI 大模型应用发展研究报告及产业趋势分析
  • RTX 4090 加速国产 AIGC 视频生成:腾讯混元与阿里通义万相部署
  • AI 浪潮下的前端演进与跨端实战指南
  • 思源黑体 NotoSansSC-Regular.otf 介绍与核心特点
  • 自然语言处理在法律领域的应用与实战
  • Web-Check 部署与远程访问实战:Docker + cpolar 内网穿透
  • 无人机路径规划算法详解
  • Python学习笔记(九):while 循环
  • AI 编程工具演进:Cursor、Kiro 与 Google Antigravity 评测
  • 荣耀发布 Robot Phone 与人形机器人,构建 AI 硬件生态
  • Claude Code 安装配置与使用指南
  • C++ 类与对象详解:封装、实例化与 this 指针
  • FPGA AD7606 串行与并行驱动实现
  • JavaScript 中 var、let、const 的核心区别与实战应用
  • OpenClaw:从认知到行动的 AI 智能体架构解析
  • 基于 Zynq FPGA 的雷龙 SD NAND 测试
  • 相关免费在线工具

    • 加密/解密文本

      使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

    • Keycode 信息

      查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

    • Escape 与 Native 编解码

      JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

    • JavaScript / HTML 格式化

      使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

    • JavaScript 压缩与混淆

      Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

    • Gemini 图片去水印

      基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online