Hard
Partition Array Into Two Arrays to Minimize Sum Difference — C++
Full explanation · Time O(n * 2^n) · Space O(2^n)
// Time: O(n * 2^n)
// Space: O(2^n)
class Solution {
public:
int minimumDifference(vector<int>& nums) {
vector<int> left, right;
for (int i = 0; i < size(nums); ++i) {
if (i < size(nums) / 2) {
left.emplace_back(nums[i]);
} else {
right.emplace_back(nums[i]);
}
}
const auto& total1 = accumulate(cbegin(left), cend(left), 0);
const auto& total2 = accumulate(cbegin(right), cend(right), 0);
const int bound = (1 << size(left));
unordered_map<int, vector<int>> sums;
for (int mask = 0; mask < bound; ++mask) {
int total = 0, bit = 1;
for (const auto& x : left) {
if (mask & bit) {
total += x;
}
bit <<= 1;
}
sums[__builtin_popcount(mask)].emplace_back(2 * total - total1);
}
for (auto& [_, v] : sums) {
sort(begin(v), end(v));
}
int result = numeric_limits<int>::max();
for (int mask = 0; mask < bound; ++mask) {
int total = 0, bit = 1;
for (const auto& x : right) {
if (mask & bit) {
total += x;
}
bit <<= 1;
}
const int k = size(right) - __builtin_popcount(mask);
const int diff = 2 * total - total2;
const auto cit = lower_bound(cbegin(sums[k]), cend(sums[k]), -diff);
if (cit != cend(sums[k])) {
result = min(result, abs(*cit + diff));
}
if (cit != cbegin(sums[k])) {
result = min(result, abs(*prev(cit) + diff));
}
}
return result;
}
};