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