news 2026/4/18 10:44:13

leetcode 3507(小根堆+懒删除)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
leetcode 3507(小根堆+懒删除)

3507: 移除最小数对使数组有序Ⅰ

思路1:小数据范围 暴力模拟

class Solution { public: int minimumPairRemoval(vector<int>& nums) { int n=nums.size(),ans=0,ap=0; bool flag=false; while(!flag){ flag=true; for(int i=1;i<n;i++){ if(nums[i]<nums[i-1]){ flag=false; break; } } if(flag==true && ap==0) return 0; ap++; if(!flag){ int min=INT_MAX,index=0; for(int i=1;i<n;i++){ int sum=nums[i]+nums[i-1]; if(sum<min){ min=sum; index=i-1; } } nums[index]=min; nums.erase(nums.begin()+index+1); n--; ans++; } else return ans; } return ans; } };

为了快速模拟题目的操作,我们需要维护三种信息:

  1. 把相邻元素和 s,以及相邻元素中的左边元素的下标i,组成一个 pair (s,i)。我们需要添加 pair、删除 pair 以及查询这些 pair 的最小值(双关键字比较),这可以用有序集合,或者懒删除堆。
  2. 维护剩余下标。我们需要查询每个下标 i 左侧最近剩余下标,以及右侧最近剩余下标。这可以用有序集合,或者两个并查集,或者双向链表。(用数组模拟)
  3. 在相邻元素中,满足「左边元素大于右边元素」(递减)的个数,记作 dec。

不断模拟操作,直到 dec=0。

题目说「用它们的和替换这对元素」,设操作的这对元素的下标为 i 和 nxt,操作相当于把 nums[i] 增加 nums[nxt],然后删除 nums[nxt]。

在这个过程中,dec 如何变化?

设操作的这对元素的下标为 i 和 nxt,i 左侧最近剩余下标为 pre,nxt 右侧最近剩余下标为 nxt2​。操作会影响 nums[i] 和 nums[nxt],也会影响周边相邻元素的大小关系。所以每次操作,我们需要重新考察 4 个元素值的大小关系,其下标从左到右为 pre,i,nxt,nxt2。

  1. 删除 nums[nxt]。如果删除前 nums[i]>nums[nxt],把 dec 减一。
  2. 如果删除前 nums[pre]>nums[i],把 dec 减一。如果删除后 nums[pre]>s,把 dec 加一。这里 s 表示操作的这对元素之和,也就是新的 nums[i] 的值。
  3. 如果删除前 nums[nxt]>nums[nxt2],把 dec 减一。删除后 i 和 nxt2相邻,如果删除后 s>nums[nxt2],把 dec 加一。

上述过程中,同时维护(添加删除)新旧相邻元素和以及下标。

思路2:懒删除堆+数组模拟双向链表

  • 用最小堆(懒删除堆)代替维护 pair 的有序集合。
  • 双向链表代替维护下标的有序集合。进一步地,可以用两个数组模拟双向链表的 prev 指针和 next 指针。
  • 如果堆顶下标 i 被删除,或者 i 右边下标 nxt 被删除,或者堆顶元素和不等于 nums[i]+nums[nxt],则弹出堆顶。
vector<int> left(n+1),right(n); ranges::iota(left,-1); //值域:-1, 0, 1, 2, ..., n-1 ranges::iota(right,1); //值域:1, 2, 3, ..., n

vector<long long> a(nums.begin(),nums.end());

right[pq.top().second]>=n || pq.top().first!=a[pq.top().second]+a[right[pq.top().second]]

这一长串判断是“懒删除”的经典写法,出现在堆/优先队列里,用来跳过那些已经失效(被合并过或移动过)的元素。

int l=left[nxt],r=right[nxt]; right[l]=r; //模拟双向链表的删除操作 left[r]=l; right[nxt]=n; //满足懒删除条件

这三行就是在用双向链表的方式把节点nxt从当前链里“逻辑删除”,而并不真的挪动数组元素。链表里再也遍历不到nxt,相当于把它“跳过”了;后续代码只要看到right[i] >= n(懒删除条件)就知道i已被删。

class Solution { public: int minimumPairRemoval(vector<int>& nums) { int n=nums.size(); //小根堆(相邻元素和,左边那个数的下标) priority_queue<pair<long long,int>,vector<pair<long long,int>>,greater<>> pq; int dec=0; //递减的相邻对的个数 for(int i=0;i<n-1;i++){ int x=nums[i],y=nums[i+1]; if(x>y) dec++; pq.emplace(x+y,i); } //每个下标的左右最近的未删除下标(映射) vector<int> left(n+1),right(n); ranges::iota(left,-1); //值域:-1, 0, 1, 2, ..., n-1 ranges::iota(right,1); //值域:1, 2, 3, ..., n vector<long long> a(nums.begin(),nums.end()); int ans=0; while(dec){ ans++; //如果堆顶数据与实际数据不符,说明堆顶数据是之前本应删除,但没有删除的数据(懒删除) while(right[pq.top().second]>=n || pq.top().first!=a[pq.top().second]+a[right[pq.top().second]]){ pq.pop(); } auto[s,i]=pq.top(); pq.pop(); //删除相邻元素和最小的一对 //(当前元素,下一个数) int nxt=right[i]; dec-=a[i]>a[nxt]; //旧数据 //(前一个数,当前元素) int pre=left[i]; if(pre>=0){ dec-=a[pre]>a[i]; //旧数据 dec+=a[pre]>s; //新数据 pq.emplace(a[pre]+s,pre); } //(下一个数,下下一个数) int nxt2=right[nxt]; if(nxt2<n){ dec-=a[nxt]>a[nxt2]; //旧数据 dec+=s>a[nxt2]; //新数据(当前元素,下下一个数) pq.emplace(s+a[nxt2],i);//nxt被删除了 } a[i]=s; //删除 nxt int l=left[nxt],r=right[nxt]; right[l]=r; //模拟双向链表的删除操作 left[r]=l; right[nxt]=n; //满足懒删除条件 } return ans; } };
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/29 5:42:33

实测分享:YOLOv13镜像在工业质检中的应用效果惊艳

实测分享&#xff1a;YOLOv13镜像在工业质检中的应用效果惊艳 在汽车零部件产线的高速传送带上&#xff0c;0.3秒内识别出微米级划痕&#xff1b;在电子元器件贴片车间&#xff0c;单帧图像精准定位27类焊点缺陷并标注置信度&#xff1b;在光伏面板质检环节&#xff0c;无需人…

作者头像 李华
网站建设 2026/4/18 5:32:28

通义千问3-14B低成本部署:Apache2.0协议下GPU按需计费方案

通义千问3-14B低成本部署&#xff1a;Apache2.0协议下GPU按需计费方案 1. 为什么Qwen3-14B是当前最值得投入的“性价比守门员” 你有没有遇到过这样的困境&#xff1a;想用大模型做业务落地&#xff0c;但30B以上模型动辄需要2张A100起步&#xff0c;显存吃紧、推理延迟高、部…

作者头像 李华
网站建设 2026/4/18 8:36:46

当AI成为Bug制造机:智能测试工具故障全景图

案例一&#xff1a;金融系统的致命误报&#xff08;信贷审批场景&#xff09; 某银行AI测试工具在验证风控系统时&#xff0c;将正常交易误判为欺诈行为的比例高达23%。根本症结在于&#xff1a; 数据污染陷阱 训练数据包含2023年信用卡盗刷特征&#xff08;占比37%&#xff0…

作者头像 李华
网站建设 2026/4/18 8:40:37

我和 XinServer 后端平台的高效开发故事

我和 XinServer 后端平台的高效开发故事 最近好几个做前端的朋友跟我吐槽&#xff0c;说接了个外包小项目&#xff0c;或者自己有个产品想法&#xff0c;结果卡在后端上了。数据库怎么设计&#xff1f;API接口怎么写&#xff1f;服务器怎么部署维护&#xff1f;光是想想就头大&…

作者头像 李华
网站建设 2026/4/18 8:43:43

Z-Image-Turbo低成本创业:个人工作室AI绘图服务搭建实战

Z-Image-Turbo低成本创业&#xff1a;个人工作室AI绘图服务搭建实战 1. 为什么Z-Image-Turbo是个人创业者的理想选择 你有没有算过一笔账&#xff1a;请一位专业画师做一张商业级产品海报&#xff0c;市场价至少300元起步&#xff0c;定制周期2-3天&#xff1b;而用Z-Image-T…

作者头像 李华
网站建设 2026/4/18 5:39:03

MinerU如何提高公式精度?LaTeX_OCR调参指南

MinerU如何提高公式精度&#xff1f;LaTeX_OCR调参指南 1. 为什么公式识别总是出错&#xff1f;从PDF提取的痛点说起 你有没有遇到过这种情况&#xff1a;辛辛苦苦用工具把一篇学术PDF转成Markdown&#xff0c;结果打开一看&#xff0c;公式全变成了乱码或者一堆“$\mathrm{x…

作者头像 李华