Skip to content

Commit 4844113

Browse files
authored
Create minimum-xor-sum-of-two-arrays.cpp
1 parent bdbe8aa commit 4844113

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

C++/minimum-xor-sum-of-two-arrays.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Time: O(n^3)
2+
// Space: O(n^2)
3+
4+
// weighted bipartite matching solution
5+
class Solution {
6+
public:
7+
int minimumXORSum(vector<int>& nums1, vector<int>& nums2) {
8+
vector<vector<int>> adj(size(nums1), vector<int>(size(nums2)));
9+
for (int i = 0; i < size(nums1); ++i) {
10+
for (int j = 0; j < size(nums2); ++j) {
11+
adj[i][j] = nums1[i] ^ nums2[j];
12+
}
13+
}
14+
return hungarian(adj).first;
15+
}
16+
17+
private:
18+
// Template modified from:
19+
// https://github.com/kth-competitive-programming/kactl/blob/main/content/graph/WeightedMatching.h
20+
pair<int, vector<int>> hungarian(const vector<vector<int>> &a) { // Time: O(n^2 * m), Space: O(n + m)
21+
if (a.empty()) return {0, {}};
22+
int n = size(a) + 1, m = size(a[0]) + 1;
23+
vector<int> u(n), v(m), p(m), ans(n - 1);
24+
for (int i = 1; i < n; ++i) {
25+
p[0] = i;
26+
int j0 = 0; // add "dummy" worker 0
27+
vector<int> dist(m, numeric_limits<int>::max()), pre(m, -1);
28+
vector<bool> done(m + 1);
29+
do { // dijkstra
30+
done[j0] = true;
31+
int i0 = p[j0], j1, delta = numeric_limits<int>::max();
32+
for (int j = 1; j < m; ++j) {
33+
if (!done[j]) {
34+
auto cur = a[i0 - 1][j - 1] - u[i0] - v[j];
35+
if (cur < dist[j]) dist[j] = cur, pre[j] = j0;
36+
if (dist[j] < delta) delta = dist[j], j1 = j;
37+
}
38+
}
39+
for (int j = 0; j < m; ++j) {
40+
if (done[j]) u[p[j]] += delta, v[j] -= delta;
41+
else dist[j] -= delta;
42+
}
43+
j0 = j1;
44+
} while (p[j0]);
45+
while (j0) { // update alternating path
46+
int j1 = pre[j0];
47+
p[j0] = p[j1], j0 = j1;
48+
}
49+
}
50+
for (int j = 1; j < m; ++j) if (p[j]) ans[p[j] - 1] = j - 1;
51+
return {-v[0], ans}; // min cost
52+
}
53+
};
54+
55+
// Time: O(n * 2^n)
56+
// Space: O(2^n)
57+
// dp solution
58+
class Solution2 {
59+
public:
60+
int minimumXORSum(vector<int>& nums1, vector<int>& nums2) {
61+
vector<pair<int, int>> dp(1 << size(nums2), {numeric_limits<int>::max(), numeric_limits<int>::max()});
62+
dp[0] = {0, 0};
63+
for (int mask = 0; mask < size(dp); ++mask) {
64+
for (int i = 0, bit = 1; i < size(nums2); ++i, bit <<= 1) {
65+
if ((mask & bit) == 0) {
66+
dp[mask | bit] = min(dp[mask | bit], {dp[mask].first + (nums1[dp[mask].second] ^ nums2[i]), dp[mask].second + 1});
67+
}
68+
}
69+
}
70+
return dp.back().first;
71+
}
72+
};

0 commit comments

Comments
 (0)