Meet in the middle
Time O(2^(n/2) × n) Space O(2^(n/2))sums(half) builds all subset sums iteratively. Sort right sums; for each left sum find the closest right sum to goal − left with a lower bound and its predecessor.
nums = [7, -9, 15, -2], goal = -5left sums of [7, -9](list)
right sums of [15, -2](list)
Step 1/5Every subset total of each half: 4 totals each instead of 16 for the whole array.
import java.util.Arrays;
class Solution {
public int minAbsDifference(int[] nums, int goal) {
int half = nums.length / 2;
long[] left = sums(nums, 0, half), right = sums(nums, half, nums.length);
Arrays.sort(right);
long best = Long.MAX_VALUE;
for (long a : left) {
long want = goal - a;
int lo = 0, hi = right.length;
while (lo < hi) {
int mid = (lo + hi) >>> 1;
if (right[mid] < want) lo = mid + 1; else hi = mid;
}
if (lo < right.length) best = Math.min(best, Math.abs(a + right[lo] - goal));
if (lo > 0) best = Math.min(best, Math.abs(a + right[lo - 1] - goal));
}
return (int) best;
}
private long[] sums(int[] nums, int from, int to) {
long[] s = new long[1 << (to - from)];
int size = 1;
for (int i = from; i < to; i++) {
for (int j = 0; j < size; j++) s[size + j] = s[j] + nums[i];
size *= 2;
}
return s;
}
}Verdict: 2⁴⁰ brute force is impossible; this is about 2 million sums.