Open In App

Find K such that sum of hamming distances between K and each Array element is minimised

Improve
Improve
Like Article
Like
Save
Share
Report

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++




// C++ code to find a number y such that
// sum of hamming distance between y
// and all the numbers given in array
// is minimum
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the number
int findNum(int arr[], int P, int N)
{
    // Creating the bits 2D array
    int bits[N + 1][P + 1];
 
    // Setting each column as 0 in row 0
    // to ensure proper
    // addition for all i upto n
    for (int i = 0; i < P; i++)
        bits[0][i + 1] = 0;
 
    // Filling the bits array
    for (int i = 0; i < N; i++) {
        int j = 1;
 
        // For each bit from 1 to P
        for (int k = 1; k <= P; k++) {
            int temp = arr[i];
            int x = 0;
 
            // If kth bit is set in temp
            // set x = 1 else x as 0
            if (temp & j)
                x = 1;
 
            // If kth bit is set
            // add x = 1 to previous value
            // in the same column
            bits[i + 1][k] = bits[i][k] + x;
 
            // Left shift j to check next bit
            j = j << 1;
        }
    }
 
    // x here is the bit contribution
    // in decimal
    int x = 1;
 
    // Declare variable to store answer
    int y = 0;
 
    // For each bit in the last row
    // check the count of 1s.
    for (int i = 1; i <= P; i++) {
 
        // If numbers of 1s is greater than
        // number of 0s then add
        // that bit's contribution to y
        // else do not add anything
        if (bits[N][i] > N / 2)
            y += x;
 
        // multiply x by 2 each time to get
        // the new bit value as at bit 0
        // value is 2^0 at bit 1 it
        // is 2^1, at bit 2 is 2^2 and so on
        x *= 2;
    }
    return y;
}
 
// Driver code
int main()
{
    int N = 4, P = 4;
 
    // Declaring the array
    int arr[N] = { 12, 11, 8, 10 };
 
    int ans = findNum(arr, P, N);
    cout << ans;
    return 0;
}


Java




// Java code to find a number y such that
// sum of hamming distance between y
// and all the numbers given in array
// is minimum
class GFG {
 
    // Function to find the number
    static int findNum(int[] arr, int P, int N) {
 
        // Creating the bits 2D array
        int[][] bits = new int[N + 1][P + 1];
 
        // Setting each column as 0 in row 0
        // to ensure proper
        // addition for all i upto n
        for (int i = 0; i < P; i++)
            bits[0][i + 1] = 0;
 
        // Filling the bits array
        for (int i = 0; i < N; i++) {
            int j = 1;
 
            // For each bit from 1 to P
            for (int k = 1; k <= P; k++) {
                int temp = arr[i];
                int x = 0;
 
                // If kth bit is set in temp
                // set x = 1 else x as 0
                if ((temp & j) != 0)
                    x = 1;
 
                // If kth bit is set
                // add x = 1 to previous value
                // in the same column
                bits[i + 1][k] = bits[i][k] + x;
 
                // Left shift j to check next bit
                j = j << 1;
            }
        }
 
        // x1 here is the bit contribution
        // in decimal
        int x1 = 1;
 
        // Declare variable to store answer
        int y = 0;
 
        // For each bit in the last row
        // check the count of 1s.
        for (int i = 1; i <= P; i++) {
 
            // If numbers of 1s is greater than
            // number of 0s then add
            // that bit's contribution to y
            // else do not add anything
            if (bits[N][i] > N / 2)
                y += x1;
 
            // multiply x by 2 each time to get
            // the new bit value as at bit 0
            // value is 2^0 at bit 1 it
            // is 2^1, at bit 2 is 2^2 and so on
            x1 *= 2;
        }
        return y;
    }
 
    // Driver code
    public static void main(String args[]) {
        int N = 4, P = 4;
 
        // Declaring the array
        int[] arr = { 12, 11, 8, 10 };
 
        int ans = findNum(arr, P, N);
        System.out.println(ans);
    }
}
 
// This code is contributed by gfgking


Python3




# Python program to implement
# the above approach
 
# Function to find the number
def findNum(arr, P, N) :
     
    # Creating the bits 2D array
    bits = [[0] * (N + 1)] * (P + 1)
 
    # Setting each column as 0 in row 0
    # to ensure proper
    # addition for all i upto n
    for i in range(0, P) :
        bits[0][i + 1] = 0
 
    # Filling the bits array
    for i in range(N) :
        j = 1
 
        # For each bit from 1 to P
        for k in range(1, P+1) :
            temp = arr[i]
            x = 0
 
            # If kth bit is set in temp
            # set x = 1 else x as 0
            if (temp & j) :
                x = 1
 
            # If kth bit is set
            # add x = 1 to previous value
            # in the same column
            bits[i + 1][k] = bits[i][k] + x
 
            # Left shift j to check next bit
            j = j << 1
         
     
 
    # x here is the bit contribution
    # in decimal
    x = 1
 
    # Declare variable to store answer
    y = 0
 
    # For each bit in the last row
    # check the count of 1s.
    for i in range(1, P+1) :
 
        # If numbers of 1s is greater than
        # number of 0s then add
        # that bit's contribution to y
        # else do not add anything
        if (bits[N][i] > N / 2) :
            y += x
 
        # multiply x by 2 each time to get
        # the new bit value as at bit 0
        # value is 2^0 at bit 1 it
        # is 2^1, at bit 2 is 2^2 and so on
        x *= 2
     
    return y
 
# Driver code
 
N = 4
P = 4
 
# Declaring the array
arr = [ 12, 11, 8, 10 ]
 
ans = findNum(arr, P, N)
 
print(ans)
 
# This code is contributed by sanjoy_62.


C#




// C# code to find a number y such that
// sum of hamming distance between y
// and all the numbers given in array
// is minimum
using System;
class GFG
{
 
  // Function to find the number
  static int findNum(int[] arr, int P, int N)
  {
 
    // Creating the bits 2D array
    int[, ] bits = new int[N + 1, P + 1];
 
    // Setting each column as 0 in row 0
    // to ensure proper
    // addition for all i upto n
    for (int i = 0; i < P; i++)
      bits[0, i + 1] = 0;
 
    // Filling the bits array
    for (int i = 0; i < N; i++) {
      int j = 1;
 
      // For each bit from 1 to P
      for (int k = 1; k <= P; k++) {
        int temp = arr[i];
        int x = 0;
 
        // If kth bit is set in temp
        // set x = 1 else x as 0
        if ((temp & j) != 0)
          x = 1;
 
        // If kth bit is set
        // add x = 1 to previous value
        // in the same column
        bits[i + 1, k] = bits[i, k] + x;
 
        // Left shift j to check next bit
        j = j << 1;
      }
    }
 
    // x1 here is the bit contribution
    // in decimal
    int x1 = 1;
 
    // Declare variable to store answer
    int y = 0;
 
    // For each bit in the last row
    // check the count of 1s.
    for (int i = 1; i <= P; i++) {
 
      // If numbers of 1s is greater than
      // number of 0s then add
      // that bit's contribution to y
      // else do not add anything
      if (bits[N, i] > N / 2)
        y += x1;
 
      // multiply x by 2 each time to get
      // the new bit value as at bit 0
      // value is 2^0 at bit 1 it
      // is 2^1, at bit 2 is 2^2 and so on
      x1 *= 2;
    }
    return y;
  }
 
  // Driver code
  public static int Main()
  {
    int N = 4, P = 4;
 
    // Declaring the array
    int[] arr = new int[4] { 12, 11, 8, 10 };
 
    int ans = findNum(arr, P, N);
    Console.Write(ans);
    return 0;
  }
}
 
// This code is contributed by Taranpreet


Javascript




<script>
       // JavaScript code for the above approach
 
       // Function to find the number
       function findNum(arr, P, N)
       {
        
           // Creating the bits 2D array
           let bits = new Array(N + 1);
 
           for (let i = 0; i < N + 1; i++) {
               bits[i] = new Array(P + 1);
           }
 
           // Setting each column as 0 in row 0
           // to ensure proper
           // addition for all i upto n
           for (let i = 0; i < P; i++)
               bits[0][i + 1] = 0;
 
           // Filling the bits array
           for (let i = 0; i < N; i++) {
               let j = 1;
 
               // For each bit from 1 to P
               for (let k = 1; k <= P; k++) {
                   let temp = arr[i];
                   let x = 0;
 
                   // If kth bit is set in temp
                   // set x = 1 else x as 0
                   if (temp & j)
                       x = 1;
 
                   // If kth bit is set
                   // add x = 1 to previous value
                   // in the same column
                   bits[i + 1][k] = bits[i][k] + x;
 
                   // Left shift j to check next bit
                   j = j << 1;
               }
           }
 
           // x here is the bit contribution
           // in decimal
           let x = 1;
 
           // Declare variable to store answer
           let y = 0;
 
           // For each bit in the last row
           // check the count of 1s.
           for (let i = 1; i <= P; i++) {
 
               // If numbers of 1s is greater than
               // number of 0s then add
               // that bit's contribution to y
               // else do not add anything
               if (bits[N][i] > Math.floor(N / 2))
                   y += x;
 
               // multiply x by 2 each time to get
               // the new bit value as at bit 0
               // value is 2^0 at bit 1 it
               // is 2^1, at bit 2 is 2^2 and so on
               x *= 2;
           }
           return y;
       }
 
       // Driver code
       let N = 4, P = 4;
 
       // Declaring the array
       let arr = [12, 11, 8, 10];
 
       let ans = findNum(arr, P, N);
       document.write(ans);
 
      // This code is contributed by Potta Lokesh
   </script>


Output

8

 

Time Complexity: O(N * P)
Auxiliary Space: O(N * P)

 



Last Updated : 10 Feb, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads