news 2026/5/8 9:19:55

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/5/6 12:37:46

Qwen-Image-Edit-2511升级实测,角色更稳定了

Qwen-Image-Edit-2511升级实测&#xff0c;角色更稳定了 标签&#xff1a; Qwen-Image-Edit、Qwen-Image-Edit-2511、AI图像编辑、AI绘图本地部署、图像一致性、LoRA模型、AI工业设计 最近在测试本地 AI 图像编辑方案时&#xff0c;我重点体验了 Qwen-Image-Edit-2511 这个新版…

作者头像 李华
网站建设 2026/5/7 22:41:51

中小企业如何低成本上线NLP?BERT镜像免费部署指南

中小企业如何低成本上线NLP&#xff1f;BERT镜像免费部署指南 1. 为什么中小企业需要“能听懂中文”的AI能力&#xff1f; 你有没有遇到过这些场景&#xff1a; 客服每天要重复回答“订单什么时候发货”“怎么修改收货地址”这类问题&#xff0c;人力成本越来越高&#xff1b…

作者头像 李华
网站建设 2026/5/1 6:49:39

为什么选择Speech Seaco Paraformer?开源可部署+高精度中文识别优势

为什么选择Speech Seaco Paraformer&#xff1f;开源可部署高精度中文识别优势 你有没有遇到过这样的场景&#xff1a;会议录音转文字错漏百出&#xff0c;专业术语全认错&#xff1b;客服录音批量处理卡在半路&#xff0c;显存爆掉&#xff1b;或者想做个本地语音助手&#x…

作者头像 李华
网站建设 2026/5/2 11:56:10

AI软件工程落地新选择:IQuest-Coder-V1多场景部署指南

AI软件工程落地新选择&#xff1a;IQuest-Coder-V1多场景部署指南 1. 为什么你需要关注IQuest-Coder-V1 你有没有遇到过这些情况&#xff1a;写一个自动化脚本&#xff0c;反复调试半天才跑通&#xff1b;接手一个老项目&#xff0c;光看懂代码逻辑就花掉一整天&#xff1b;在…

作者头像 李华
网站建设 2026/5/4 23:15:29

5个高效开源模型镜像推荐:DeepSeek-R1-Distill-Qwen-1.5B免配置部署

5个高效开源模型镜像推荐&#xff1a;DeepSeek-R1-Distill-Qwen-1.5B免配置部署 你是不是也遇到过这样的问题&#xff1a;想用一个强大的AI模型做文本生成&#xff0c;但光是环境配置就折腾半天&#xff1f;下载模型慢、依赖冲突、CUDA版本不匹配……这些问题让人望而却步。今…

作者头像 李华
网站建设 2026/5/1 7:13:26

Llama3-8B科研辅助应用:论文润色系统部署实战教程

Llama3-8B科研辅助应用&#xff1a;论文润色系统部署实战教程 你是不是也经常为英文论文的语言表达发愁&#xff1f;语法不够地道、用词不够精准、逻辑衔接生硬——这些问题&#xff0c;过去只能靠反复修改或请母语者润色。但现在&#xff0c;借助本地部署的大模型&#xff0c…

作者头像 李华