You are given an integer array nums and an integer goal.
You want to choose a subsequence of nums such that the sum of its elements is the closest possible to goal. That is, if the sum of the subsequence’s elements is sum, then you want to minimize the absolute differenceabs(sum - goal).
Return theminimum possible value ofabs(sum - goal).
Note that a subsequence of an array is an array formed by removing some elements (possibly all or none) of the original array.
Input: nums =[5,-7,3,5], goal =6Output: 0Explanation: Choose the whole array as a subsequence,with a sum of 6.This is equal to the goal, so the absolute difference is0.
Input: nums =[7,-9,15,-2], goal =-5Output: 1Explanation: Choose the subsequence [7,-9,-2],with a sum of -4.The absolute difference isabs(-4-(-5))= abs(1)=1, which is the minimum.
Since the array is small (≤ 40), we can split it into two halves and enumerate all possible subsequence sums for each half. For each sum in the first half, we can use binary search in the second half to find the sum that, when combined, is closest to the goal.
classSolution {
public:int minAbsDifference(vector<int>& nums, int goal) {
int n = nums.size(), n1 = n /2, n2 = n - n1;
vector<int> A, B;
for (int i =0; i < n1; ++i) A.push_back(nums[i]);
for (int i = n1; i < n; ++i) B.push_back(nums[i]);
vector<int> sa, sb;
for (int mask =0; mask < (1<< n1); ++mask) {
int s =0;
for (int i =0; i < n1; ++i) if (mask & (1<< i)) s += A[i];
sa.push_back(s);
}
for (int mask =0; mask < (1<< n2); ++mask) {
int s =0;
for (int i =0; i < n2; ++i) if (mask & (1<< i)) s += B[i];
sb.push_back(s);
}
sort(sb.begin(), sb.end());
int ans = abs(goal);
for (int x : sa) {
int t = goal - x;
auto it = lower_bound(sb.begin(), sb.end(), t);
if (it != sb.end()) ans = min(ans, abs(x +*it - goal));
if (it != sb.begin()) ans = min(ans, abs(x +*(--it) - goal));
}
return ans;
}
};
classSolution {
publicintminAbsDifference(int[] nums, int goal) {
int n = nums.length, n1 = n / 2, n2 = n - n1;
int[] A = Arrays.copyOfRange(nums, 0, n1);
int[] B = Arrays.copyOfRange(nums, n1, n);
List<Integer> sa =new ArrayList<>(), sb =new ArrayList<>();
for (int mask = 0; mask < (1 << n1); mask++) {
int s = 0;
for (int i = 0; i < n1; i++) if ((mask & (1 << i)) != 0) s += A[i];
sa.add(s);
}
for (int mask = 0; mask < (1 << n2); mask++) {
int s = 0;
for (int i = 0; i < n2; i++) if ((mask & (1 << i)) != 0) s += B[i];
sb.add(s);
}
Collections.sort(sb);
int ans = Math.abs(goal);
for (int x : sa) {
int t = goal - x;
int idx = Collections.binarySearch(sb, t);
if (idx < 0) idx =-idx - 1;
if (idx < sb.size()) ans = Math.min(ans, Math.abs(x + sb.get(idx) - goal));
if (idx > 0) ans = Math.min(ans, Math.abs(x + sb.get(idx - 1) - goal));
}
return ans;
}
}
classSolution {
funminAbsDifference(nums: IntArray, goal: Int): Int {
val n = nums.size
val n1 = n / 2val n2 = n - n1
val A = nums.sliceArray(0 until n1)
val B = nums.sliceArray(n1 until n)
val sa = mutableListOf<Int>()
val sb = mutableListOf<Int>()
for (mask in0 until (1 shl n1)) {
var s = 0for (i in0 until n1) if ((mask and (1 shl i)) !=0) s += A[i]
sa.add(s)
}
for (mask in0 until (1 shl n2)) {
var s = 0for (i in0 until n2) if ((mask and (1 shl i)) !=0) s += B[i]
sb.add(s)
}
sb.sort()
var ans = kotlin.math.abs(goal)
for (x in sa) {
val t = goal - x
val idx = sb.binarySearch(t).let { if (it < 0) -it - 1elseit }
if (idx < sb.size) ans = minOf(ans, kotlin.math.abs(x + sb[idx] - goal))
if (idx > 0) ans = minOf(ans, kotlin.math.abs(x + sb[idx - 1] - goal))
}
return ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classSolution:
defminAbsDifference(self, nums: list[int], goal: int) -> int:
from bisect import bisect_left
n = len(nums)
n1 = n //2 n2 = n - n1
A, B = nums[:n1], nums[n1:]
sa = [sum(A[i] for i in range(n1) if mask & (1<< i)) for mask in range(1<< n1)]
sb = [sum(B[i] for i in range(n2) if mask & (1<< i)) for mask in range(1<< n2)]
sb.sort()
ans = abs(goal)
for x in sa:
t = goal - x
idx = bisect_left(sb, t)
if idx < len(sb):
ans = min(ans, abs(x + sb[idx] - goal))
if idx >0:
ans = min(ans, abs(x + sb[idx -1] - goal))
return ans
impl Solution {
pubfnmin_abs_difference(nums: Vec<i32>, goal: i32) -> i32 {
let n = nums.len();
let n1 = n /2;
let n2 = n - n1;
let a =&nums[..n1];
let b =&nums[n1..];
letmut sa =vec![];
letmut sb =vec![];
for mask in0..(1<< n1) {
letmut s =0;
for i in0..n1 {
if (mask & (1<< i)) !=0 {
s += a[i];
}
}
sa.push(s);
}
for mask in0..(1<< n2) {
letmut s =0;
for i in0..n2 {
if (mask & (1<< i)) !=0 {
s += b[i];
}
}
sb.push(s);
}
sb.sort();
letmut ans = goal.abs();
for&x in&sa {
let t = goal - x;
let idx = sb.binary_search(&t).unwrap_or_else(|i| i);
if idx < sb.len() {
ans = ans.min((x + sb[idx] - goal).abs());
}
if idx >0 {
ans = ans.min((x + sb[idx -1] - goal).abs());
}
}
ans
}
}