给定大小为n的正整数数组。求出AND最大值的三元组的计数,并在i
例子:
Input : a[] = {1, 2, 3, 4, 5, 6}
Output : 1 4
Explanation: Maximum number that can formed is 4 ( 4 & 5 & 6 ) and only 1 triplet is possible.
Input : a[] = {4, 11, 10, 15, 26}
Output : 4 10
Explanation: Maximum number that can formed is 10. There are 4 triplets possible – {11, 10, 15}, {11, 10, 26}, {11, 15, 26}, {10, 15, 26}
天真的方法是使用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中转换为其二进制。