Total Hamming Distance
Given an integer array arr[], return the sum of Hamming distances between all the pairs of the integers in arr.
The Hamming distance between two integers is the number of bit positions at which the corresponding bits are different.
Note: The answer is guaranteed to fit within a 32-bit integer.
Examples:
Input: arr[] = [1, 14]
Output: 4
Explanation: Binary representations of 1 is 0001, 14 is 1110. The answer will be:
HammingDist(1, 14) = 4.Input: arr[] = [4, 14, 4, 14]
Output: 8
Explanation: Binary representations of 4 is 0100, 14 is 1110. The answer will be:
HammingDist(4, 14) + HammingDist(4, 4) + HammingDist(4, 14) + HammingDist(14, 4) + HammingDist(14, 14) + HammingDist(4, 14) = 2 + 0 + 2 + 2 + 0 + 2 = 8.
[Naive Approach] - Checking Each Pair - O(n^2) Time and O(1) Space
We iterate through all pairs using nested loops and compute the Hamming distance for each pair by checking differing bits. For each bit position, if the two numbers have different values, we increment the total count. The final sum gives the total Hamming distance across all pairs.
#include <bits/stdc++.h>
using namespace std;
// Function to calculate the total Hamming distance between all pairs
int totHammingDist(vector<int>& arr) {
int count = 0;
int n = arr.size();
// Loop through all unique pairs (i, j)
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
// For each bit position from 0 to 30
for (int k = 0; k < 31; k++) {
// If bit k is set in arr[i] and not in arr[j]
if ((arr[i] & (1 << k)) && !(arr[j] & (1 << k))) {
count++;
}
// If bit k is not set in arr[i] and is set in arr[j]
else if (!(arr[i] & (1 << k)) && (arr[j] & (1 << k))) {
count++;
}
}
}
}
// Return the total count of differing bits (Hamming distance)
return count;
}
int main() {
vector<int> arr = {4, 14, 4, 14};
int ans = totHammingDist(arr);
cout << ans << endl;
return 0;
}
import java.util.*;
public class GfG {
// Function to calculate the total Hamming distance between all pairs
static int totHammingDist(int[] arr) {
int count = 0;
int n = arr.length;
// Iterate over all unique pairs (i, j)
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
// For each bit position from 0 to 30
for (int k = 0; k < 31; k++) {
// Check if the k-th bit differs between
// arr[i] and arr[j]
// arr[i] has bit k set, arr[j] does not
if (((arr[i] & (1 << k)) != 0) &&
((arr[j] & (1 << k)) == 0)) {
count++;
}
// arr[i] has bit k unset, arr[j] has it set
if (((arr[i] & (1 << k)) == 0) &&
((arr[j] & (1 << k)) != 0)) {
count++;
}
}
}
}
// Return total Hamming distance
return count;
}
public static void main(String[] args) {
int[] arr = {4, 14, 4, 14};
int ans = totHammingDist(arr);
System.out.println(ans);
}
}
def totHammingDist(arr):
count = 0
n = len(arr)
# Loop through all unique pairs (i, j) in the array
for i in range(n):
for j in range(i + 1, n):
# For each bit position from 0 to 30
for k in range(31):
# Check if the k-th bit is different between
# arr[i] and arr[j]
# k-th bit is set in arr[i] but not in arr[j]
if (arr[i] & (1 << k)) and not (arr[j] & (1 << k)):
count += 1
# k-th bit is not set in arr[i]
# but is set in arr[j]
if not (arr[i] & (1 << k)) and (arr[j] & (1 << k)):
count += 1
# Return total Hamming distance across all pairs
return count
# Driver code
if __name__ == "__main__":
arr = [4, 14, 4, 14]
ans = totHammingDist(arr)
print(ans)
using System;
class GfG {
// Function to calculate total Hamming distance between
// all unique pairs in the array
static int totHammingDist(int[] arr) {
int count = 0;
int n = arr.Length;
// Loop through all unique pairs (i, j)
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
// For each bit position from 0 to 30
for (int k = 0; k < 31; k++) {
// Check if the k-th bit is different between arr[i] and arr[j]
// bit k is set in arr[i] but not in arr[j]
if (((arr[i] & (1 << k)) != 0) &&
((arr[j] & (1 << k)) == 0)) {
count++;
}
// bit k is not set in arr[i] but is set in arr[j]
if (((arr[i] & (1 << k)) == 0) &&
((arr[j] & (1 << k)) != 0)) {
count++;
}
}
}
}
// Return the total Hamming distance
return count;
}
// Main method to test the function
static void Main() {
int[] arr = { 4, 14, 4, 14 };
int ans = totHammingDist(arr);
Console.WriteLine(ans);
}
}
function totHammingDist(arr) {
let count = 0;
let n = arr.length;
// Loop through all unique pairs (i, j) in the array
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
// For each bit position from 0 to 30
for (let k = 0; k < 31; k++) {
// Check if the k-th bit is different in arr[i] and arr[j]
// k-th bit is set in arr[i] but not in arr[j]
if ((arr[i] & (1 << k)) && !(arr[j] & (1 << k))) {
count++;
}
// k-th bit is not set in arr[i] but is set in arr[j]
if(!(arr[i] & (1 << k)) && (arr[j] & (1 << k))) {
count++;
}
}
}
}
// Return the total Hamming distance between all pairs
return count;
}
// Driver code
let arr = [4, 14, 4, 14];
let ans = totHammingDist(arr);
console.log(ans);
Output
8
[Expected Approach] - Bitwise Frequency Counting Using Array - O(n) Time and O(1) Space
This approach counts the number of
1
s at each bit position (0 to 31) across all numbers in the array. The total Hamming distance is calculated by multiplying the count of1
s with the count of0
s at each position, as every differing bit contributes to the total distance.
#include <bits/stdc++.h>
using namespace std;
// Function to calculate the total Hamming Distance
// among all pairs in the array
int totHammingDist(vector<int> &arr){
int n = arr.size();
int count = 0;
vector<int> countone(32, 0);
// Count how many numbers have the j-th bit set
for (int i = 0; i < n; i++){
for (int j = 0; j < 32; j++){
// Check if j-th bit is set in arr[i]
if ((arr[i] & (1 << j))){
countone[j]++;
}
}
}
// For each bit position, compute contribution to Hamming distance
for (int j = 0; j < 32; j++){
// countone[j] elements have this bit set
// n - countone[j] elements have this bit unset
// Each differing pair contributes 1 to the Hamming distance
count += countone[j] * (n - countone[j]);
}
return count;
}
int main(){
vector<int> arr = {4, 14, 4, 14};
int ans = totHammingDist(arr);
cout << ans << endl;
return 0;
}
import java.util.*;
class GfG {
static int totHammingDist(int[] arr) {
int n = arr.length;
int count = 0;
int[] countOne = new int[32];
// Count how many numbers have the j-th bit set
for (int num : arr) {
for (int j = 0; j < 32; j++) {
// Check if j-th bit is set in the current number
if ((num & (1 << j)) != 0) {
countOne[j]++;
}
}
}
// Calculate Hamming distance contributed by each bit position
for (int j = 0; j < 32; j++) {
// countOne[j] numbers have the j-th bit set
// (n - countOne[j]) numbers have the j-th bit unset
// Each such pair contributes 1 to the Hamming Distance
count += countOne[j] * (n - countOne[j]);
}
// Return the total Hamming Distance
return count;
}
public static void main(String[] args) {
int[] arr = { 4, 14, 4, 14 };
int ans = totHammingDist(arr);
System.out.println(ans);
}
}
def totHammingDist(arr):
n = len(arr)
count = 0
count_one = [0] * 32
# Count how many numbers have the j-th bit set
for num in arr:
for j in range(32):
if num & (1 << j):
count_one[j] += 1
# Calculate total Hamming distance
for j in range(32):
# Each pair where one bit is set and
# the other is not contributes 1 to the distance
count += count_one[j] * (n - count_one[j])
return count
# Driver code
if __name__ == "__main__":
arr = [4, 14, 4, 14]
ans = totHammingDist(arr)
print(ans)
using System;
class GfG {
// Function to calculate the total Hamming distance between all pairs
static int totHammingDist(int[] arr){
int n = arr.Length;
int count = 0;
int[] countone = new int[32];
// Count the number of 1s at each bit position for all numbers
for (int i = 0; i < n; i++) {
for (int j = 0; j < 32; j++) {
// Check if the j-th bit is set in arr[i]
if ((arr[i] & (1 << j)) != 0) {
countone[j]++;
}
}
}
// Calculate the total Hamming distance using bit counts
for (int j = 0; j < 32; j++) {
// (n - countone[j]) = number of elements with the j-th
// bit not set Each differing pair at this bit
// position contributes 1 to the Hamming distance
count += countone[j] * (n - countone[j]);
}
return count;
}
// Main method (entry point)
static void Main(){
int[] arr = { 4, 14, 4, 14 };
int ans = totHammingDist(arr);
Console.WriteLine(ans);
}
}
function totHammingDist(arr){
let n = arr.length;
let count = 0;
// Array to store the count of 1s at each bit position (0 to 31)
let countone = new Array(32).fill(0);
// Count the number of 1s at each bit position for all elements
for (let i = 0; i < n; i++) {
for (let j = 0; j < 32; j++) {
// Check if the j-th bit is set in arr[i]
if ((arr[i] & (1 << j)) !== 0) {
countone[j]++;
}
}
}
// Calculate the total Hamming distance
for (let j = 0; j < 32; j++) {
// (n - countone[j]): number of elements where the j-th bit is 0
// Each pair (1, 0) contributes 1 to the Hamming distance
count += countone[j] * (n - countone[j]);
}
return count;
}
// Driver Code
let arr = [4, 14, 4, 14];
console.log(totHammingDist(arr));
Output
8