Find K such that sum of hamming distances between K and each Array element is minimised
Given an array arr[] of N non-negative integers and an integer P (1 ≤ P ≤ 30), which denotes the upper limit of any number in the array to be (2P – 1). The task is to find a number such that the sum of Hamming distances between the number itself and all the numbers in the array is minimum. If there are multiple answers possible print any one of them.
Note: Hamming distance between two numbers is the number of positions in their binary representation in which the bits of the numbers are different
Examples:
Input: N = 4, P = 4
arr[] = {12, 11, 8, 10}
Output: 8
Explanation: The number 8 has minimum sum of hamming distances.
Hamming distance from 12: 1
Hamming distance from 11: 2
Hamming distance from 8: 0
Hamming distance from 10: 1
10 can also be a valid answer.
Input: N = 3, P = 3
arr[] = {5, 2, 7}
Output: 7
Approach: This problem can be solved using Greedy approach and bits manipulation. With observation, it can be said that In the final answer, only those bits will be set which have higher number of 1s for all array elements compared to 0s. Because otherwise, the total sum of different bits will increase. Follow the steps mentioned below to solve the problem:
- Create a 2D array bits[][] to keep count of bits for all numbers at each of the P bit positions.
- Start iterating the array from the start.
- For each array element increase the count of bit for each set bit in the bits[][] array.
- After iteration is over check the total number of set bits in the bits array.
- If the number of set bits in a position is greater than the number of 0s in that bit position set that bit in resultant number as 1, otherwise as 0.
- Return the final number as result.
Illustration:
For example take the array, arr[] = {12, 11, 8, 10} and P = 4.
Now see the bit representation of the numbers in the following image:
Logical Representation
From the above image it can be clearly seen that the least significant bit has more number of 0s compared to 1s.
Similarly 3rd bit and the most significant bit have more number of 0s and 1s respectively.
But the 2nd bit has same number of 0s and 1s.
So the resultant number can have binary representation 1010 or 1000 i.e. it can be 10 or 8.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int findNum( int arr[], int P, int N)
{
int bits[N + 1][P + 1];
for ( int i = 0; i < P; i++)
bits[0][i + 1] = 0;
for ( int i = 0; i < N; i++) {
int j = 1;
for ( int k = 1; k <= P; k++) {
int temp = arr[i];
int x = 0;
if (temp & j)
x = 1;
bits[i + 1][k] = bits[i][k] + x;
j = j << 1;
}
}
int x = 1;
int y = 0;
for ( int i = 1; i <= P; i++) {
if (bits[N][i] > N / 2)
y += x;
x *= 2;
}
return y;
}
int main()
{
int N = 4, P = 4;
int arr[N] = { 12, 11, 8, 10 };
int ans = findNum(arr, P, N);
cout << ans;
return 0;
}
|
Java
class GFG {
static int findNum( int [] arr, int P, int N) {
int [][] bits = new int [N + 1 ][P + 1 ];
for ( int i = 0 ; i < P; i++)
bits[ 0 ][i + 1 ] = 0 ;
for ( int i = 0 ; i < N; i++) {
int j = 1 ;
for ( int k = 1 ; k <= P; k++) {
int temp = arr[i];
int x = 0 ;
if ((temp & j) != 0 )
x = 1 ;
bits[i + 1 ][k] = bits[i][k] + x;
j = j << 1 ;
}
}
int x1 = 1 ;
int y = 0 ;
for ( int i = 1 ; i <= P; i++) {
if (bits[N][i] > N / 2 )
y += x1;
x1 *= 2 ;
}
return y;
}
public static void main(String args[]) {
int N = 4 , P = 4 ;
int [] arr = { 12 , 11 , 8 , 10 };
int ans = findNum(arr, P, N);
System.out.println(ans);
}
}
|
Python3
def findNum(arr, P, N) :
bits = [[ 0 ] * (N + 1 )] * (P + 1 )
for i in range ( 0 , P) :
bits[ 0 ][i + 1 ] = 0
for i in range (N) :
j = 1
for k in range ( 1 , P + 1 ) :
temp = arr[i]
x = 0
if (temp & j) :
x = 1
bits[i + 1 ][k] = bits[i][k] + x
j = j << 1
x = 1
y = 0
for i in range ( 1 , P + 1 ) :
if (bits[N][i] > N / 2 ) :
y + = x
x * = 2
return y
N = 4
P = 4
arr = [ 12 , 11 , 8 , 10 ]
ans = findNum(arr, P, N)
print (ans)
|
C#
using System;
class GFG
{
static int findNum( int [] arr, int P, int N)
{
int [, ] bits = new int [N + 1, P + 1];
for ( int i = 0; i < P; i++)
bits[0, i + 1] = 0;
for ( int i = 0; i < N; i++) {
int j = 1;
for ( int k = 1; k <= P; k++) {
int temp = arr[i];
int x = 0;
if ((temp & j) != 0)
x = 1;
bits[i + 1, k] = bits[i, k] + x;
j = j << 1;
}
}
int x1 = 1;
int y = 0;
for ( int i = 1; i <= P; i++) {
if (bits[N, i] > N / 2)
y += x1;
x1 *= 2;
}
return y;
}
public static int Main()
{
int N = 4, P = 4;
int [] arr = new int [4] { 12, 11, 8, 10 };
int ans = findNum(arr, P, N);
Console.Write(ans);
return 0;
}
}
|
Javascript
<script>
function findNum(arr, P, N)
{
let bits = new Array(N + 1);
for (let i = 0; i < N + 1; i++) {
bits[i] = new Array(P + 1);
}
for (let i = 0; i < P; i++)
bits[0][i + 1] = 0;
for (let i = 0; i < N; i++) {
let j = 1;
for (let k = 1; k <= P; k++) {
let temp = arr[i];
let x = 0;
if (temp & j)
x = 1;
bits[i + 1][k] = bits[i][k] + x;
j = j << 1;
}
}
let x = 1;
let y = 0;
for (let i = 1; i <= P; i++) {
if (bits[N][i] > Math.floor(N / 2))
y += x;
x *= 2;
}
return y;
}
let N = 4, P = 4;
let arr = [12, 11, 8, 10];
let ans = findNum(arr, P, N);
document.write(ans);
</script>
|
Time Complexity: O(N * P)
Auxiliary Space: O(N * P)
Last Updated :
10 Feb, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...