一刷 06/2022
Version #1 Two Half Combination + TreeSet
Time - n/2*2^(n/2)*lg(2^(n/2)) = n^2 * 2^(n/2)
Space O(n * 2^(n/2))
class Solution {
public int minAbsDifference(int[] nums, int goal) {
// Select half of the nums, compute all the combinations of those nums
// System.out.printf("%s\n", combination(nums, 0, 1).toString());
List<Integer> firstHalfComb = combination(nums, 0, nums.length / 2);
List<Integer> secondHalfComb = combination(nums, nums.length / 2 + 1, nums.length - 1);
TreeSet<Integer> secondHalf = new TreeSet<>(secondHalfComb);
int min = Integer.MAX_VALUE;
for (Integer comb : firstHalfComb) {
int diff = goal - comb;
if (secondHalfComb.size() == 0) {
min = Math.min(min, Math.abs(diff));
continue;
}
Integer h = secondHalf.ceiling(diff);
if (h != null) {
min = Math.min(min, Math.abs(h - diff));
}
Integer l = secondHalf.floor(diff);
if (l != null) {
min = Math.min(min, Math.abs(l - diff));
}
if (min == 0) {
break;
}
}
return min;
}
private List<Integer> combination(int[] nums, int start, int end) {
if (end < start) {
return new ArrayList<>();
}
// [start, end] inclusive -> end + start + 1 numbers
int n = end - start + 1;
int max = 1 << n;
// System.out.printf("max=%d\n", max);
List<Integer> result = new ArrayList<>();
for (int mask = 0; mask < max; mask++) {
// System.out.printf("mask:%d\n", mask);
int sum = 0;
for (int shift = 0; shift < n; shift++) {
if (((mask >> shift) & 1) != 0) {
sum += nums[start + shift];
}
}
result.add(sum);
}
return result;
}
}
No comments:
Post a Comment