找到 K 使得 K 和每个 Array 元素之间的汉明距离之和最小化
给定一个包含N个非负整数的数组arr[]和一个整数P (1 ≤ P ≤ 30) ,它表示数组中任何数字的上限为(2 P – 1) 。任务是找到一个数字,使得该数字本身与数组中所有数字之间的汉明距离之和最小。如果可能有多个答案,请打印其中任何一个。
注意:两个数字之间的汉明距离是其二进制表示中数字的位不同的位置数
例子:
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
方法:这个问题可以使用贪心方法和位操作来解决。通过观察,可以说在最终答案中,只有那些与 0 相比,所有数组元素的 1 数量更多的位才会被设置。因为否则,不同位的总和会增加。请按照以下步骤解决问题:
- 创建一个 2D 数组bits[][]以保持每个 P 位位置的所有数字的位数。
- 从头开始迭代数组。
- 对于每个数组元素,增加bits[][]数组中每个设置位的位数。
- 迭代结束后,检查位数组中设置位的总数。
- 如果某个位置的设置位数大于该位位置中 0 的数量,则将该位在结果数中设置为 1,否则设置为 0。
- 返回最终数字作为结果。
插图:
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:
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.
下面是上述方法的实现。
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
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
8
时间复杂度: O(N * P)
辅助空间: O(N * P)