Sum the differing bits over every pair of numbers. The trick isn't faster pair comparison — it's refusing to look at pairs at all, and counting one bit column at a time.
Hamming distance between two numbers = how many bit positions differ, which is exactly the set-bit count of
a XOR b. The task is the sum of that over every unordered pair. For [4,14,2] the three
pairwise distances are 2, 1, 3 → total 6. The obvious approach compares all
n(n−1)/2 pairs — O(n²), too slow for large arrays.
Hamming distance is additive across bit positions and positions don't interact, so the double sum can be reordered: instead of "for each pair, sum over bits," compute "for each bit, sum over pairs." At one fixed bit, every number shows a 0 or a 1. A pair differs there exactly when one side is a 1 and the other a 0.
It's Σpairs Σbits = Σbits Σpairs — the same total,
counted in a smarter order.
At one bit, the numbers split into a "1" team and a "0" team. Every cross-team handshake is a differing
pair: ones × zeros, and no same-team handshake counts.
Line the numbers up in binary and read down each column. One column's answer needs only its count of 1s — the rows (the actual numbers) stop mattering.
Don't build each pair and score it. Ask how much each bit contributes to the grand total, and add those up. The pairs are never enumerated.
Enter numbers and step bit by bit. The current column highlights: 1-cells teal, 0-cells terracotta. The meters show that column's
ones, zeros, its ones × zeros contribution, and the running total. Every
other column dims so you can see one handshake-count at a time. Click any column header to jump to it.
Try 7 7 7 (every column all-same → every
contribution 0) or 0 7 (three columns of 1×1 → total 3). The grid shows only the bits actually
used.
| bit | column (4,14,2) | ones | zeros | ones × zeros |
|---|---|---|---|---|
| 0 | 0, 0, 0 | 0 | 3 | 0 |
| 1 | 0, 1, 1 | 2 | 1 | 2 |
| 2 | 1, 1, 0 | 2 | 1 | 2 |
| 3 | 0, 1, 0 | 1 | 2 | 2 |
Total = 0 + 2 + 2 + 2 = 6 — and the three individual Hamming distances
(4,14)=2, (4,2)=1, (14,2)=3 were never computed. Every differing bit of every pair got counted
exactly once, in column order.
int totalHammingDistance(int[] nums) { int n = nums.length; long total = 0; for (int bit = 0; bit < 31; bit++) { int ones = 0; for (int num : nums) ones += (num >> bit) & 1; // count 1s in this column total += (long) ones * (n - ones); // ones × zeros } return (int) total; }
O(31·n) = O(n) time, O(1) space. A one-pass variant tallies an int[31] of column
counts first, then sums the products — same complexity, counts each number's bits once.
Σpairs Σbits differ(i,j,b). Since bits are independent, swap the sums
to Σbits Σpairs. At a fixed bit, a pair contributes iff one endpoint is a 1
and the other a 0 — there are exactly ones × zeros such pairs.
No /2 is needed: the two endpoints come from disjoint groups, so each unordered pair is
generated once (A from ones, C from zeros gives A–C, never also C–A). That's different from
C(ones,2), which would count same-bit pairs — the opposite of what Hamming distance wants.
The nested i,j loop is O(n²). If the score decomposes by bit, count each bit's contribution
globally instead.
That counts pairs that agree. Hamming wants pairs that differ — the cross product
ones × zeros, no halving.
A single fold a^b^c… loses the per-bit counts. Arrays with equal total XOR can have different
pairwise totals.
Knowing how many 1s overall isn't enough — you need the count per bit position. Keep the columns separate.
ones × zeros and the running total can pass INT_MAX. Accumulate in long, cast once at the end.
When a problem asks for a sum of some property over every pair and that property decomposes
into independent components (here, bits), swap the order of counting: for each component, count how many pairs
it contributes to. Quadratic pair enumeration collapses to O(B·n) with B a small
constant.
Three questions unlock the whole family: can the score split into independent components? For one component,
what makes a pair contribute? Can I count those pairs without listing them? Here: bits, differing bits, and
ones × zeros.