力扣: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
  • -105 <= nums[i][j] <= 105
  • 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区间。

AC代码:

C++:

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

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; } }

Read more

Flutter 三方库 a2a 的鸿蒙化适配指南 - 实现高效的 Array-to-Array 结构转换、支持跨维度数据映射与集合内容深度克隆

Flutter 三方库 a2a 的鸿蒙化适配指南 - 实现高效的 Array-to-Array 结构转换、支持跨维度数据映射与集合内容深度克隆

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 a2a 的鸿蒙化适配指南 - 实现高效的 Array-to-Array 结构转换、支持跨维度数据映射与集合内容深度克隆 前言 在进行 Flutter for OpenHarmony 的大规模数据处理或图形计算开发时,经常需要对多维数组(嵌套列表)进行结构化调整。例如,将一个扁平化的传感器采样序列转换为 UI 渲染所需的网格坐标点集。a2a 是一个专门为 Array-to-Array 转换设计的极简工具库。它致力于通过声明式的 API 解决集合变换过程中的逻辑繁琐问题。本文将探讨如何在鸿蒙端利用该库提升集合操作的优雅度。 一、原原理性解析 / 概念介绍 1.1 基础原理 a2a 建立在一套强大的“映射算子(Mapping Operators)”之上。它获取输入数组,通过定义的投影(Project)

By Ne0inhk
鸿蒙金融理财全栈项目——运维监控、性能优化、安全加固

鸿蒙金融理财全栈项目——运维监控、性能优化、安全加固

《鸿蒙APP开发从入门到精通》第20篇:鸿蒙金融理财全栈项目——运维监控、性能优化、安全加固 📊🔧🛡️ 内容承接与核心价值 这是《鸿蒙APP开发从入门到精通》的第20篇——运维监控、性能优化、安全加固篇,100%承接第19篇的生态合作、用户运营、数据变现架构,并基于金融场景的运维监控、性能优化、安全加固要求,设计并实现鸿蒙金融理财全栈项目的运维监控、性能优化、安全加固功能。 学习目标: * 掌握鸿蒙金融理财项目的运维监控设计与实现; * 实现应用监控、服务器监控、数据库监控; * 理解性能优化在金融场景的核心设计与实现; * 实现前端优化、后端优化、数据库优化; * 掌握安全加固在金融场景的设计与实现; * 实现代码加固、数据加密、安全审计; * 优化金融理财项目的用户体验(运维监控、性能优化、安全加固)。 学习重点: * 鸿蒙金融理财项目的运维监控设计原则; * 性能优化在金融场景的应用; * 安全加固在金融场景的设计要点。 一、 运维监控基础 🎯 1.1 运维监控定义 运维监控是指对金融理财项目的应用、

By Ne0inhk

Mac mini 4 docker 安装openclaw

mac 通过docker 本地安装openclaw 教程 OpenClaw 不仅仅是一个聊天机器人,而是一个功能强大的 AI 智能体执行框架。你可以把它想象成一个能自主思考、调用工具、并替你完成复杂任务的数字员工。 1.环境准备 1.1安装Docker Desktop for mac 官网 下载安装即可 docker 中设置加速地址 "registry-mirrors": [ "https://docker.m.daocloud.io", "http://hub-mirror.c.163.com", "https://mirror.baidubce.com", "https://docker.mirrors.

By Ne0inhk
Flutter 三方库 media_kit 极致视听的全能播放器内核(音视频旗舰引擎,深度适配鸿蒙 HarmonyOS Next ohos)

Flutter 三方库 media_kit 极致视听的全能播放器内核(音视频旗舰引擎,深度适配鸿蒙 HarmonyOS Next ohos)

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net。 欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net。 前言 在鸿蒙(OpenHarmony)应用中实现极致的音视频播放体验,media_kit 是理想的旗舰级引擎。基于强大的 libmpv 核心,它提供了硬件加速、全格式支持以及灵活的渲染接口。 ⚠️ 重要说明:media_kit 官方版本(pub.dev)尚未原生支持鸿蒙系统。AtomGit 上的 OpenHarmony-SIG 社区已开始对该插件进行鸿蒙适配,但在实际部署到鸿蒙真机时,我们发现仍存在两个关键阻塞问题需要手动修复。 本文将详细记录: 1. 适配过程中遇到的两个核心问题及其修复方案。 2. media_kit 在鸿蒙平台的 API 使用方法。 3. 当前适配的完成度与后续展望。 一、核心价值 1.1

By Ne0inhk