3510: 移除最小数对使数组有序Ⅱ
题干同 leetcode 3507
区别:(数据规模增大)
1 <= nums.length <= 50 (3507)-1000 <= nums[i] <= 1000
1 <= nums.length <= 105 (3510)-109 <= nums[i] <= 109
暴力模拟方法仅针对小数据范围,用于本题会超时。
思路:懒删除堆+数组模拟双向链表(详解见leetcode 3507)
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);
ranges::iota(right,1);
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);
}
a[i]=s;
int l=left[nxt],r=right[nxt];
right[l]=r;
left[r]=l;
right[nxt]=n;
}
return ans;
}
};