2163. 删除元素后和的最小差值
思路:本题的本质思路是将数组分成两半,在前半段选出k个值最小的组合,在后半段也是选出k个值最大的组合。
我们可以通过一层for循环,来处理前半段,即[k,2k]这里每个位置对应的最小k个数的总和。后半段的处理过程一样。
再进行一次for循环,来对这个分界点进行遍历,最后时间复杂度为0(n)。
class Solution {
public:
long long minimumDifference(vector<int>& nums) {
int n=nums.size(),k=n/3;
vector<long long> s1(2*k,0),s2(3*k,0);
priority_queue<int> q1;
for(int i=0;i<2*k;i++){
if(i!=0) s1[i]=s1[i-1];
s1[i]+=nums[i];
q1.push(nums[i]);
if(q1.size()>k){
s1[i]-=q1.top();
q1.pop();
}
}
priority_queue<int ,vector<int>,greater<int>> q2;
for(int i=n-1;i>k-1;i--){
if(i!=n-1) s2[i]=s2[i+1];
s2[i]+=nums[i];
q2.push(nums[i]);
if(q2.size()>k){
s2[i]-=q2.top();
q2.pop();
}
}
long long minn=LONG_LONG_MAX;
for(int i=k-1;i<2*k;i++){
if(minn>s1[i]-s2[i+1]) minn=s1[i]-s2[i+1];
}
return minn;
}
};