思路:看到n是40,很容易想到复杂度是指数阶的。
但是直接暴力枚举的话,2^40肯定TLE。
那么很容易想到我们分开两部分 一部分各20个算出来所有组合情况。
处理完所有组合情况后,我们对左半部分从小到大排序,对右半部分从大到小排序。这样子我们可以利用双指针计算出来答案。
左半部分我当前指向了这个部分的最小值。
右半部分我当前指向了这个部分的最大值。
计算出来的x和goal去比较,
如果x>goal,那么我们要去减少x,那么其实就只能移动右半部分的指针,因为右半部分才能减小。
如果x<goal,那么我们需要增加x,而左半部分是可以增加的,所以就移动左指针。
class Solution {
public:
vector<int> get_sum(vector<int>nums){
vector<int> ans(1<<nums.size());
for(int i=0;i<ans.size();i++){
for(int j=0;j<nums.size();j++){
if(i>>j&1) ans[i]+=nums[j];
}
}
return ans;
}
int minAbsDifference(vector<int>& nums, int goal) {
vector<int> L=get_sum({nums.begin(),nums.begin()+nums.size()/2});
vector<int> R=get_sum({nums.begin()+nums.size()/2,nums.end()});
sort(L.begin(),L.end());
sort(R.rbegin(),R.rend());
int l=0,r=0;
int ans=2e9;
while(l<L.size() && r<R.size()){
int x=L[l]+R[r];
ans=min(ans,abs(x-goal));
if(x>=goal) ++r;
else ++l;
}
return ans;
}
};