📜  计算数组中K位不同的所有对

📅  最后修改于: 2021-05-07 07:17:01             🧑  作者: Mango

给定一个大小为n且整数为k的数组,请对数组中所有对进行计数,这些对在两个数字的二进制表示形式的正好K位方面有所不同。
输入数组的元素值较小,并且可能有很多重复。
例子:

Input: arr[] = {2, 4, 1, 3, 1}
       k = 2       
Output: 5
Explanation:
There are only 4 pairs which differs in 
exactly 2 bits of binary representation:
(2, 4), (1, 2) [Two times] and (4, 1)
[Two times]

Input  : arr[] = {2, 1, 2, 1}
         k = 2
Output :  4
我们强烈建议您单击此处并进行实践,然后再继续解决方案。

天真的方法

蛮力是在两个循环中一个接一个地运行两个循环,一个接一个地选择对,然后对两个元素进行异或运算。 XORed值的结果包含两个元素中都不同的设置位。现在,我们只需要计算总的设置位,以便将其与值K进行比较。
下面是上述方法的实现:

C++
// C++ program to count all pairs with bit difference
// as k
#include
using namespace std;
 
// Utility function to count total ones in a number
int bitCount(int n)
{
    int count = 0;
    while (n)
    {
        if (n & 1)
            ++count;
        n >>= 1;
    }
    return count;
}
 
// Function to count pairs of K different bits
long long countPairsWithKDiff(int arr[], int n, int k)
{
    long long ans = 0; // initialize final answer
 
    for (int i = 0; i < n-1; ++i)
    {
        for (int j = i + 1; j < n; ++j)
        {
            int xoredNum = arr[i] ^ arr[j];
 
            // Check for K differ bit
            if (k == bitCount(xoredNum))
                ++ans;
        }
    }
    return ans;
}
 
// Driver code
int main()
{
    int k = 2;
    int arr[] = {2, 4, 1, 3, 1};
    int n = sizeof(arr)/sizeof(arr[0]);
 
    cout << "Total pairs for k = " << k << " are "
         << countPairsWithKDiff(arr, n, k) << "\n";
 
    return 0;
}


Java
// Java program to count all pairs with bit difference
// as k
 
import java.io.*;
 
class GFG {
 
 
// Utility function to count total ones in a number
static int bitCount(int n)
{
    int count = 0;
    while (n>0)
    {
        if ((n & 1)>0)
            ++count;
        n >>= 1;
    }
    return count;
}
 
// Function to count pairs of K different bits
static long countPairsWithKDiff(int arr[], int n, int k)
{
    long  ans = 0; // initialize final answer
 
    for (int i = 0; i < n-1; ++i)
    {
        for (int j = i + 1; j < n; ++j)
        {
            int xoredNum = arr[i] ^ arr[j];
 
            // Check for K differ bit
            if (k == bitCount(xoredNum))
                ++ans;
        }
    }
    return ans;
}
 
// Driver code
 
    public static void main (String[] args) {
            int k = 2;
    int arr[] = {2, 4, 1, 3, 1};
    int n =arr.length;
 
    System.out.println( "Total pairs for k = " + k + " are "
        + countPairsWithKDiff(arr, n, k) + "\n");
    }
}
// This code is contributed by shs..


Python3
# Python 3 program to count all pairs
# with bit difference as k
 
# Utility function to count total
# ones in a number
def bitCount(n):
    count = 0
    while (n):
        if (n & 1):
            count += 1
        n >>= 1
 
    return count
 
# Function to count pairs of K different bits
def countPairsWithKDiff(arr, n, k):
    ans = 0
     
    # initialize final answer
    for i in range(0, n - 1, 1):
        for j in range(i + 1, n, 1):
            xoredNum = arr[i] ^ arr[j]
 
            # Check for K differ bit
            if (k == bitCount(xoredNum)):
                ans += 1
 
    return ans
 
# Driver code
if __name__ == '__main__':
    k = 2
    arr = [2, 4, 1, 3, 1]
    n = len(arr)
 
    print("Total pairs for k =", k, "are",
           countPairsWithKDiff(arr, n, k))
 
# This code is contributed by
# Sanjit_Prasad


C#
// C# program to count all pairs
// with bit difference as k
using System;
 
class GFG
{
 
// Utility function to count
// total ones in a number
static int bitCount(int n)
{
    int count = 0;
    while (n > 0)
    {
        if ((n & 1) > 0)
            ++count;
        n >>= 1;
    }
    return count;
}
 
// Function to count pairs of K different bits
static long countPairsWithKDiff(int []arr,
                                int n, int k)
{
    long ans = 0; // initialize final answer
 
    for (int i = 0; i < n-1; ++i)
    {
        for (int j = i + 1; j < n; ++j)
        {
            int xoredNum = arr[i] ^ arr[j];
 
            // Check for K differ bit
            if (k == bitCount(xoredNum))
                ++ans;
        }
    }
    return ans;
}
 
// Driver code
public static void Main ()
{
    int k = 2;
    int []arr = {2, 4, 1, 3, 1};
    int n = arr.Length;
     
    Console.WriteLine( "Total pairs for k = " +
                                  k + " are " +
        countPairsWithKDiff(arr, n, k) + "\n");
}
}
 
// This code is contributed by shs..


PHP
>= 1;
    }
    return $count;
}
 
// Function to count pairs
// of K different bits
function countPairsWithKDiff($arr, $n, $k)
{
     
    // initialize final answer
    $ans = 0;
 
    for ($i = 0; $i < $n-1; ++$i)
    {
        for ($j = $i + 1; $j < $n; ++$j)
        {
            $xoredNum = $arr[$i] ^ $arr[$j];
 
            // Check for K differ bit
            if ($k == bitCount($xoredNum))
                ++$ans;
        }
    }
    return $ans;
}
 
    // Driver code
    $k = 2;
    $arr = array(2, 4, 1, 3, 1);
    $n = count($arr);
 
    echo "Total pairs for k = " , $k , " are "
        , countPairsWithKDiff($arr, $n, $k) , "\n";
 
// This code is contributed by anuj_67.
?>


Javascript


C++
// Below is C++ approach of finding total k bit
// difference pairs
#include
using namespace std;
 
// Function to calculate K bit different pairs in array
long long kBitDifferencePairs(int arr[], int n, int k)
{
    // Get the maximum value among all array elemensts
    int MAX = *max_element(arr, arr+n);
 
    // Set the count array to 0, count[] stores the
    // total frequency of array elements
    long long count[MAX+1];
    memset(count, 0, sizeof(count));
 
    for (int i=0; i < n; ++i)
        ++count[arr[i]];
 
    // Initialize result
    long long ans = 0;
 
    // For 0 bit answer will be total count of same number
    if (k == 0)
    {
        for (int i = 0; i <= MAX; ++i)
            ans += (count[i] * (count[i] - 1)) / 2;
 
        return ans;
    }
 
 
    for (int i = 0; i <= MAX; ++i)
    {
        // if count[i] is 0, skip the next loop as it
        // will not contribute the answer
        if (!count[i])
           continue;
 
        for (int j = i + 1; j <= MAX; ++j)
        {
            //Update answer if k differ bit found
            if ( __builtin_popcount(i ^ j) == k)
                ans += count[i] * count[j];
        }
    }
    return ans;
}
 
// Driver code
int main()
{
    int k = 2;
    int arr[] = {2, 4, 1, 3, 1};
    int n = sizeof(arr)/sizeof(arr[0]);
 
    cout << "Total pairs for k = " << k << " are = "
         << kBitDifferencePairs(arr, n, k) << "\n";
 
    k = 3;
    cout << "Total pairs for k = " << k << " are = "
         << kBitDifferencePairs(arr, n, k) ;
    return 0;
}


Java
// Below is Java approach of finding total k bit
// difference pairs
import java.util.*;
 
class GFG
{
 
// Function to calculate K bit
// different pairs in array
static long kBitDifferencePairs(int arr[],
                                int n, int k)
{
    // Get the maximum value among all array elemensts
    int MAX = Arrays.stream(arr).max().getAsInt();
 
    // Set the count array to 0,
    // count[] stores the total
    // frequency of array elements
    long []count = new long[MAX + 1];
    Arrays.fill(count, 0);
 
    for (int i = 0; i < n; ++i)
        ++count[arr[i]];
 
    // Initialize result
    long ans = 0;
 
    // For 0 bit answer will be total
    // count of same number
    if (k == 0)
    {
        for (int i = 0; i <= MAX; ++i)
            ans += (count[i] * (count[i] - 1)) / 2;
 
        return ans;
    }
 
    for (int i = 0; i <= MAX; ++i)
    {
        // if count[i] is 0, skip the next loop
        // as it will not contribute the answer
        if (count[i] == 0)
        continue;
 
        for (int j = i + 1; j <= MAX; ++j)
        {
            // Update answer if k differ bit found
            if ( Integer.bitCount(i ^ j) == k)
                ans += count[i] * count[j];
        }
    }
    return ans;
}
 
// Driver code
public static void main(String[] args)
{
    int k = 2;
    int arr[] = {2, 4, 1, 3, 1};
    int n = arr.length;
 
    System.out.println("Total pairs for k = " +
                                k + " are = " +
                        kBitDifferencePairs(arr, n, k));
 
    k = 3;
    System.out.println("Total pairs for k = " +
                                k + " are = " +
                        kBitDifferencePairs(arr, n, k));
    }
}
 
// This code is contributed by Rajput-Ji


Python3
# Below is Python3 approach of finding
# total k bit difference pairs
 
# Function to calculate K bit different
# pairs in array
def kBitDifferencePairs(arr, n, k):
 
    # Get the maximum value among
    # all array elemensts
    MAX = max(arr)
 
    # Set the count array to 0, count[] stores
    # the total frequency of array elements
    count = [0 for i in range(MAX + 1)]
 
    for i in range(n):
        count[arr[i]] += 1
 
    # Initialize result
    ans = 0
 
    # For 0 bit answer will be total
    # count of same number
    if (k == 0):
        for i in range(MAX + 1):
            ans += (count[i] * (count[i] - 1)) // 2
 
        return ans
 
 
    for i in range(MAX + 1):
         
        # if count[i] is 0, skip the next loop
        # as it will not contribute the answer
        if (count[i] == 0):
            continue
 
        for j in range(i + 1, MAX + 1):
             
            # Update answer if k differ bit found
            if (bin(i ^ j).count('1') == k):
                ans += count[i] * count[j]
     
    return ans
 
# Driver code
k = 2
arr = [2, 4, 1, 3, 1]
n = len(arr)
 
print("Total pairs for k =", k, "are",
       kBitDifferencePairs(arr, n, k))
 
k = 3
print("Total pairs for k =", k, "are",
       kBitDifferencePairs(arr, n, k))
 
# This code is contributed by mohit kumar


C#
// Below is C# approach of finding
// total k bit difference pairs
using System;
using System.Linq;
 
class GFG
{
 
// Function to calculate K bit
// different pairs in array
static long kBitDifferencePairs(int []arr,
                                int n, int k)
{
    // Get the maximum value among
    // all array elemensts
    int MAX = arr.Max();
 
    // Set the count array to 0,
    // count[] stores the total
    // frequency of array elements
    long []count = new long[MAX + 1];
 
    for (int i = 0; i < n; ++i)
        ++count[arr[i]];
 
    // Initialize result
    long ans = 0;
 
    // For 0 bit answer will be total
    // count of same number
    if (k == 0)
    {
        for (int i = 0; i <= MAX; ++i)
            ans += (count[i] * 
                   (count[i] - 1)) / 2;
 
        return ans;
    }
 
    for (int i = 0; i <= MAX; ++i)
    {
        // if count[i] is 0, skip the next loop
        // as it will not contribute the answer
        if (count[i] == 0)
        continue;
 
        for (int j = i + 1; j <= MAX; ++j)
        {
            // Update answer if k differ bit found
            if (BitCount(i ^ j) == k)
                ans += count[i] * count[j];
        }
    }
    return ans;
}
 
static int BitCount(int n)
{
    int count = 0;
    while (n > 0)
    {
        count += n & 1;
        n >>= 1;
    }
    return count;
}
 
// Driver code
public static void Main(String[] args)
{
    int k = 2;
    int []arr = {2, 4, 1, 3, 1};
    int n = arr.Length;
 
    Console.WriteLine("Total pairs for k = " +
                               k + " are = " +
                       kBitDifferencePairs(arr, n, k));
 
    k = 3;
    Console.WriteLine("Total pairs for k = " +
                               k + " are = " +
                       kBitDifferencePairs(arr, n, k));
    }
}
 
// This code is contributed by PrinciRaj1992


输出:

Total pairs for k = 2 are 5

时间复杂度: O(N 2 * log MAX)其中MAX是输入数组中的最大元素。
辅助空间: O(1)

高效的方法

对于输入数组具有较小元素且可能有很多重复的情况,此方法非常有效。这个想法是从0迭代到max(arr [i]),对于每对(i,j),检查(i ^ j)中的设置位数,并将其与K进行比较。我们可以使用gcc()的内置函数__builtin_popcount)或预先计算这样的数组以使检查更快。如果i ^ j中的个数等于K,则将i和j的总数相加。

C++

// Below is C++ approach of finding total k bit
// difference pairs
#include
using namespace std;
 
// Function to calculate K bit different pairs in array
long long kBitDifferencePairs(int arr[], int n, int k)
{
    // Get the maximum value among all array elemensts
    int MAX = *max_element(arr, arr+n);
 
    // Set the count array to 0, count[] stores the
    // total frequency of array elements
    long long count[MAX+1];
    memset(count, 0, sizeof(count));
 
    for (int i=0; i < n; ++i)
        ++count[arr[i]];
 
    // Initialize result
    long long ans = 0;
 
    // For 0 bit answer will be total count of same number
    if (k == 0)
    {
        for (int i = 0; i <= MAX; ++i)
            ans += (count[i] * (count[i] - 1)) / 2;
 
        return ans;
    }
 
 
    for (int i = 0; i <= MAX; ++i)
    {
        // if count[i] is 0, skip the next loop as it
        // will not contribute the answer
        if (!count[i])
           continue;
 
        for (int j = i + 1; j <= MAX; ++j)
        {
            //Update answer if k differ bit found
            if ( __builtin_popcount(i ^ j) == k)
                ans += count[i] * count[j];
        }
    }
    return ans;
}
 
// Driver code
int main()
{
    int k = 2;
    int arr[] = {2, 4, 1, 3, 1};
    int n = sizeof(arr)/sizeof(arr[0]);
 
    cout << "Total pairs for k = " << k << " are = "
         << kBitDifferencePairs(arr, n, k) << "\n";
 
    k = 3;
    cout << "Total pairs for k = " << k << " are = "
         << kBitDifferencePairs(arr, n, k) ;
    return 0;
}

Java

// Below is Java approach of finding total k bit
// difference pairs
import java.util.*;
 
class GFG
{
 
// Function to calculate K bit
// different pairs in array
static long kBitDifferencePairs(int arr[],
                                int n, int k)
{
    // Get the maximum value among all array elemensts
    int MAX = Arrays.stream(arr).max().getAsInt();
 
    // Set the count array to 0,
    // count[] stores the total
    // frequency of array elements
    long []count = new long[MAX + 1];
    Arrays.fill(count, 0);
 
    for (int i = 0; i < n; ++i)
        ++count[arr[i]];
 
    // Initialize result
    long ans = 0;
 
    // For 0 bit answer will be total
    // count of same number
    if (k == 0)
    {
        for (int i = 0; i <= MAX; ++i)
            ans += (count[i] * (count[i] - 1)) / 2;
 
        return ans;
    }
 
    for (int i = 0; i <= MAX; ++i)
    {
        // if count[i] is 0, skip the next loop
        // as it will not contribute the answer
        if (count[i] == 0)
        continue;
 
        for (int j = i + 1; j <= MAX; ++j)
        {
            // Update answer if k differ bit found
            if ( Integer.bitCount(i ^ j) == k)
                ans += count[i] * count[j];
        }
    }
    return ans;
}
 
// Driver code
public static void main(String[] args)
{
    int k = 2;
    int arr[] = {2, 4, 1, 3, 1};
    int n = arr.length;
 
    System.out.println("Total pairs for k = " +
                                k + " are = " +
                        kBitDifferencePairs(arr, n, k));
 
    k = 3;
    System.out.println("Total pairs for k = " +
                                k + " are = " +
                        kBitDifferencePairs(arr, n, k));
    }
}
 
// This code is contributed by Rajput-Ji

Python3

# Below is Python3 approach of finding
# total k bit difference pairs
 
# Function to calculate K bit different
# pairs in array
def kBitDifferencePairs(arr, n, k):
 
    # Get the maximum value among
    # all array elemensts
    MAX = max(arr)
 
    # Set the count array to 0, count[] stores
    # the total frequency of array elements
    count = [0 for i in range(MAX + 1)]
 
    for i in range(n):
        count[arr[i]] += 1
 
    # Initialize result
    ans = 0
 
    # For 0 bit answer will be total
    # count of same number
    if (k == 0):
        for i in range(MAX + 1):
            ans += (count[i] * (count[i] - 1)) // 2
 
        return ans
 
 
    for i in range(MAX + 1):
         
        # if count[i] is 0, skip the next loop
        # as it will not contribute the answer
        if (count[i] == 0):
            continue
 
        for j in range(i + 1, MAX + 1):
             
            # Update answer if k differ bit found
            if (bin(i ^ j).count('1') == k):
                ans += count[i] * count[j]
     
    return ans
 
# Driver code
k = 2
arr = [2, 4, 1, 3, 1]
n = len(arr)
 
print("Total pairs for k =", k, "are",
       kBitDifferencePairs(arr, n, k))
 
k = 3
print("Total pairs for k =", k, "are",
       kBitDifferencePairs(arr, n, k))
 
# This code is contributed by mohit kumar

C#

// Below is C# approach of finding
// total k bit difference pairs
using System;
using System.Linq;
 
class GFG
{
 
// Function to calculate K bit
// different pairs in array
static long kBitDifferencePairs(int []arr,
                                int n, int k)
{
    // Get the maximum value among
    // all array elemensts
    int MAX = arr.Max();
 
    // Set the count array to 0,
    // count[] stores the total
    // frequency of array elements
    long []count = new long[MAX + 1];
 
    for (int i = 0; i < n; ++i)
        ++count[arr[i]];
 
    // Initialize result
    long ans = 0;
 
    // For 0 bit answer will be total
    // count of same number
    if (k == 0)
    {
        for (int i = 0; i <= MAX; ++i)
            ans += (count[i] * 
                   (count[i] - 1)) / 2;
 
        return ans;
    }
 
    for (int i = 0; i <= MAX; ++i)
    {
        // if count[i] is 0, skip the next loop
        // as it will not contribute the answer
        if (count[i] == 0)
        continue;
 
        for (int j = i + 1; j <= MAX; ++j)
        {
            // Update answer if k differ bit found
            if (BitCount(i ^ j) == k)
                ans += count[i] * count[j];
        }
    }
    return ans;
}
 
static int BitCount(int n)
{
    int count = 0;
    while (n > 0)
    {
        count += n & 1;
        n >>= 1;
    }
    return count;
}
 
// Driver code
public static void Main(String[] args)
{
    int k = 2;
    int []arr = {2, 4, 1, 3, 1};
    int n = arr.Length;
 
    Console.WriteLine("Total pairs for k = " +
                               k + " are = " +
                       kBitDifferencePairs(arr, n, k));
 
    k = 3;
    Console.WriteLine("Total pairs for k = " +
                               k + " are = " +
                       kBitDifferencePairs(arr, n, k));
    }
}
 
// This code is contributed by PrinciRaj1992

输出:

Total pairs for k = 2 are = 5