📌  相关文章
📜  在AND为最大的数组中查找三元组

📅  最后修改于: 2021-04-22 00:47:05             🧑  作者: Mango

给定大小为n的正整数数组。求出AND最大值的三元组的计数,并在i 假设数字不大于10 ^ 9

例子:

天真的方法是使用3个循环并生成所有三元组,并计算可形成的最大数量和此类三元组的计数。
时间复杂度: O(N ^ 3)

更好的方法是先用二进制表示形式表示数字,然后将其存储在2d数组中。由于该数字不能大于2 ^ 32(由于问题中给出的约束),因此每个数字最多需要32次迭代。我们还将采用布尔值标志数组,该数组将代表可以使用哪些所有数字构成最大三元组。最初,我们将数组设置为true,因为可以使用每个数字。
设最大AND数为X,最初为零。
现在我们要最大化X,因此我们开始从代表该数字的第32位的索引开始遍历2D表,然后对存在于三胞胎可用的数字的第32位(即其标志)的1的数量进行计数是真的。如果1的个数大于等于3,则意味着可以设置三元组来设置X的第i个位,那么我们将设置所有未设置第i个位的数字的标志,并加上i的幂否则,如果计数少于3,则X的第i个将不被设置,并且由于该位可以有1和0的组合,因此我们不需要更改数字的标志。
我们将以相反的顺序(从32到0)对每个位重复上述过程。
在处,我们将计算设置了其标志的数字的数量,使其为r。然后,对于三元组的数量,我们只需要计算rC3 {r *(r-1)*(r-2)/ 6}。

C++
// CPP program to find triplet with maximum
// bitwise AND.
#include "cmath"
#include "cstring"
#include "iostream"
using namespace std;
  
int maxTriplet(int a[], int n)
{
    // Flag Array initially set to true
    // for all numbers
    bool f[n];
    memset(f, true, sizeof(f));
  
    // 2D array for bit representation
    // of all the numbers.
    // Initially all bits are set to 0.
    int bits[n][33];
    memset(bits, 0, sizeof(bits));
  
    for (int i = 0; i < n; ++i) {
        int num = a[i];
        int j = 32;
  
        // Finding bit representation
        // of every number and
        // storing it in bits array.
        while (num) {
  
            // Checking last bit of the number
            if (num & 1) {
                bits[i][j] = 1;
            }
  
            j--;
  
            // Dividing number by 2.
            num >>= 1;
        }
    }
  
    // maximum And number initially 0.
    long long ans = 0;
  
    // Traversing the 2d binary representation.
    // 0th index represents 32th bits
    // while 32th index represents 0th bit.
    for (long long i = 0; i <= 32; ++i) {
        int cnt = 0;
  
        for (int j = 0; j < n; ++j) {
            if (bits[j][i] and f[j]) {
                cnt++;
            }
        }
  
        // If cnt greater than 3 then (32-i)th bits
        // of the number will be set.
        if (cnt >= 3) {
  
            ans += pow(2LL, 32 - i);
  
            // Setting flags of the numbers
            // whose ith bit is not set.
            for (int j = 0; j < n; ++j) {
                if (!bits[j][i]) {
                    f[j] = false;
                }
            }
        }
    }
  
    // Counting the numbers whose flag are true.
    int cnt = 0;
    for (int i = 0; i < n; ++i) {
        if (f[i]) {
            cnt++;
        }
    }
  
    long long NumberOfTriplets = 
          (cnt * (cnt - 1) * (cnt - 2)) / 6;
  
    cout << NumberOfTriplets << " " << ans;
}
  
int main(int argc, char const* argv[])
{
    int a[] = { 4, 11, 10, 15, 26 };
    int n = sizeof(a) / sizeof(a[0]);
    maxTriplet(a, n);
    return 0;
}


Java
// Java program to find triplet with maximum
// bitwise AND.
import java.util.Arrays;
  
class GFG {
      
static void maxTriplet(int a[], int n)
{
    // Flag Array initially set to true
    // for all numbers
    boolean []f = new boolean[n];
    Arrays.fill(f, true);
  
    // 2D array for bit representation
    // of all the numbers.
    // Initially all bits are set to 0.
    int bits[][] = new int[n][33];
  
    for (int i = 0; i < n; ++i)
    {
        int num = a[i];
        int j = 32;
  
        // Finding bit representation
        // of every number and
        // storing it in bits array.
        while (num > 0)
        {
            // Checking last bit of the number
            if (num % 2 == 1) 
            {
                bits[i][j] = 1;
            }
              
            j--;
  
            // Dividing number by 2.
            num >>= 1;
        }
    }
      
    // maximum And number initially 0.
    long ans = 0;
  
    // Traversing the 2d binary representation.
    // 0th index represents 32th bits
    // while 32th index represents 0th bit.
    for (int i = 0; i <= 32; ++i) 
    {
        int cnt = 0;
  
        for (int j = 0; j < n; ++j) 
        {
            if (bits[j][i] == 1 & f[j])
            {
                cnt++;
            }
        }
  
        // If cnt greater than 3 then (32-i)th bits
        // of the number will be set.
        if (cnt >= 3) {
  
            ans += Math.pow(2, 32 - i);
  
            // Setting flags of the numbers
            // whose ith bit is not set.
            for (int j = 0; j < n; ++j) {
                if (bits[j][i] != 1) {
                    f[j] = false;
                }
            }
        }
    }
  
    // Counting the numbers whose flag are true.
    int cnt = 0;
    for (int i = 0; i < n; ++i) {
        if (f[i]) {
            cnt++;
        }
    }
  
    long NumberOfTriplets = (cnt * (cnt - 1) * (cnt - 2)) / 6;
  
    System.out.print(NumberOfTriplets + " " + ans);
}
  
// Driver code
public static void main(String[] args) {
int a[] = { 4, 11, 10, 15, 26 };
    int n = a.length;
    maxTriplet(a, n);
      
}
}
  
// This code is contributed by PrinciRaj1992


Python3
# Python3 program to find triplet with 
# maximum bitwise AND.
def maxTriplet(a, n):
  
    # Flag Array initially set to true
    # for all numbers
    f = [True for i in range(n)]
  
    # 2D array for bit representation
    # of all the numbers.
    # Initially all bits are set to 0.
    bits = [[0 for i in range(33)] 
               for i in range(n)]
  
    for i in range(n): 
        num = a[i]
        j = 32
  
        # Finding bit representation
        # of every number and
        # storing it in bits array.
        while (num):
  
            # Checking last bit of the number
            if (num & 1) :
                bits[i][j] = 1
              
            j -= 1
  
            # Dividing number by 2.
            num >>= 1
          
    # maximum And number initially 0.
    ans = 0
  
    # Traversing the 2d binary representation.
    # 0th index represents 32th bits
    # while 32th index represents 0th bit.
    for i in range(33): 
        cnt = 0
  
        for j in range(n): 
            if (bits[j][i] and f[j]):
                cnt += 1
              
        # If cnt greater than 3 then (32-i)th 
        # bits of the number will be set.
        if (cnt >= 3): 
  
            ans += pow(2, 32 - i)
  
            # Setting flags of the numbers
            # whose ith bit is not set.
            for j in range(n): 
                if (bits[j][i] == False) :
                    f[j] = False
  
    # Counting the numbers whose 
    # flag are true.
    cnt = 0
    for i in range(n): 
        if (f[i]):
            cnt += 1
          
    NumberOfTriplets = (cnt * (cnt - 1) * (cnt - 2)) // 6
    print(NumberOfTriplets, ans)
  
# Driver Code
a = [ 4, 11, 10, 15, 26] 
n = len(a)
maxTriplet(a, n)
  
# This code is contributed by Mohit Kumar29


C#
// C# program to find triplet with maximum
// bitwise AND.
using System;
class GFG 
{
static void maxTriplet(int []a, int n)
{
    // Flag Array initially set to true
    // for all numbers
    Boolean []f = new Boolean[n];
    for (int i = 0; i < n; ++i)
        f[i] = true;
  
    // 2D array for bit representation
    // of all the numbers.
    // Initially all bits are set to 0.
    int [,]bits = new int[n, 33];
  
    for (int i = 0; i < n; ++i)
    {
        int num = a[i];
        int j = 32;
  
        // Finding bit representation
        // of every number and
        // storing it in bits array.
        while (num > 0)
        {
            // Checking last bit of the number
            if (num % 2 == 1) 
            {
                bits[i, j] = 1;
            }
              
            j--;
  
            // Dividing number by 2.
            num >>= 1;
        }
    }
      
    // maximum And number initially 0.
    long ans = 0;
    int cnt;
      
    // Traversing the 2d binary representation.
    // 0th index represents 32th bits
    // while 32th index represents 0th bit.
    for (int i = 0; i <= 32; ++i) 
    {
        cnt = 0;
  
        for (int j = 0; j < n; ++j) 
        {
            if (bits[j, i] == 1 & f[j])
            {
                cnt++;
            }
        }
  
        // If cnt greater than 3 then (32-i)th bits
        // of the number will be set.
        if (cnt >= 3) 
        {
            ans += (long)Math.Pow(2, 32 - i);
  
            // Setting flags of the numbers
            // whose ith bit is not set.
            for (int j = 0; j < n; ++j) 
            {
                if (bits[j, i] != 1) 
                {
                    f[j] = false;
                }
            }
        }
    }
  
    // Counting the numbers whose flag are true.
    cnt = 0;
    for (int i = 0; i < n; ++i) 
    {
        if (f[i])
        {
            cnt++;
        }
    }
  
    long NumberOfTriplets = (cnt * (cnt - 1) * 
                            (cnt - 2)) / 6;
  
    Console.Write(NumberOfTriplets + " " + ans);
}
  
// Driver code
public static void Main(String[] args)
{
    int []a = { 4, 11, 10, 15, 26 };
    int n = a.Length;
    maxTriplet(a, n);
}
}
  
// This code is contributed by Rajput-Ji


输出:
4 10

时间复杂度: O(NlogN)
由于每个数字都可以在logN中转换为其二进制。