Count pairs whose sum consists of set bits only
Given an array arr[] consisting of N integers, the task is to find the count of unordered pairs in the given array whose sum contains all set bits.
Examples:
Input: arr[] = {1, 2, 5}
Output: 2
Explanation: Possible pairs satisfying the conditions are:
- (1, 2): 1 + 2 = 3 (11) all bits are set in binary representation of 3.
- 2) (2, 5): 2 + 5 = 7 (111) all bits are set in binary representation of 7.
Therefore, the count is 2.
Input: arr[] = {1, 2, 5, 10}
Output: 3
Explanation: Possible pairs satisfying the conditions are:
- (1, 2): 1 + 2 = 3 (11) all bits are set in binary representation of 3.
- (2, 5): 2 + 5 = 7 (111) all bits are set in binary representation of 7.
- (5, 10): 5 + 10 = 15(1111) all bits are set in binary representation of 15.
Naive Approach: The idea is to generate all the possible pairs and check whether their sum has all bits set or not. If found to be true, then count that pair in the resultant count. Print the count after checking all the pairs.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool allSetBits( int num)
{
int totalBits = log2(num) + 1;
int setBits = __builtin_popcount(num);
if (totalBits == setBits)
return true ;
else
return false ;
}
int countPairs( int arr[], int n)
{
int ans = 0;
for ( int i = 0; i < n; i++) {
for ( int j = i + 1; j < n; j++) {
int sum = arr[i] + arr[j];
if (allSetBits(sum))
ans++;
}
}
return ans;
}
int main()
{
int arr[] = { 1, 2, 5, 10 };
int N = sizeof (arr) / sizeof (arr[0]);
cout << countPairs(arr, N);
return 0;
}
|
Java
import java.util.*;
class GFG{
static boolean allSetBits( int num)
{
int totalBits = ( int )Math.log(num) + 1 ;
int setBits = Integer.bitCount(num);
if (totalBits == setBits)
return true ;
else
return false ;
}
static int countPairs( int arr[],
int n)
{
int ans = 0 ;
for ( int i = 0 ; i < n; i++)
{
for ( int j = i + 1 ; j < n; j++)
{
int sum = arr[i] + arr[j];
if (allSetBits(sum))
ans++;
}
}
return ans;
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 5 , 10 };
int N = arr.length;
System.out.print(countPairs(arr, N));
}
}
|
Python3
from math import log2
def allSetBits(num):
totalBits = int (log2(num) + 1 )
setBits = bin (num).count( '1' )
if (totalBits = = setBits):
return True
else :
return False
def countPairs(arr, n):
ans = 0
for i in range (n):
for j in range (i + 1 , n):
sum = arr[i] + arr[j]
if (allSetBits( sum )):
ans + = 1
return ans
if __name__ = = '__main__' :
arr = [ 1 , 2 , 5 , 10 ]
N = len (arr)
print (countPairs(arr, N))
|
C#
using System;
class GFG{
static int countSetBits( int n)
{
int count = 0;
while (n > 0)
{
count += n & 1;
n >>= 1;
}
return count;
}
static bool allSetBits( int num)
{
int totalBits = ( int )Math.Log(num) + 1;
int setBits = countSetBits(num);
if (totalBits == setBits)
return true ;
else
return false ;
}
static int countPairs( int []arr,
int n)
{
int ans = 0;
for ( int i = 0; i < n; i++)
{
for ( int j = i + 1; j < n; j++)
{
int sum = arr[i] + arr[j];
if (allSetBits(sum))
ans++;
}
}
return ans;
}
public static void Main(String[] args)
{
int []arr = {1, 2, 5, 10};
int N = arr.Length;
Console.Write(countPairs(arr, N));
}
}
|
Javascript
<script>
function countSetBits(n)
{
let count = 0;
while (n > 0)
{
count += n & 1;
n >>= 1;
}
return count;
}
function allSetBits(num)
{
let totalBits = Math.floor(Math.log(num)) + 1;
let setBits = countSetBits(num);
if (totalBits == setBits)
return true ;
else
return false ;
}
function countPairs(arr, n)
{
let ans = 0;
for (let i = 0; i < n; i++)
{
for (let j = i + 1; j < n; j++)
{
let sum = arr[i] + arr[j];
if (allSetBits(sum))
ans++;
}
}
return ans;
}
let arr = [ 1, 2, 5, 10 ];
let N = arr.length;
document.write(countPairs(arr, N));
</script>
|
Time Complexity: O(N2log N), where N is the size of the given array.
Auxiliary Space: O(1)
Efficient Approach: The key observation is that there are only log N numbers from 0 to N which contains all set bits. This property can be utilized to optimize the above approach. Follow the below steps to solve the problem:
- Store all the log(MAX_INTEGER) elements in an array setArray[].
- Map all the elements of the array arr[] in a Map data structure where an element is a key and its frequency is the value.
- Traverse the given array arr[] over the range [0, N – 1] and in nested loop traverse the array setArray[] from j = 0 to log(MAX_INTEGER) and increment ans by map[setArray[j] – arr[i]] where ans stores the total number of required pairs.
- As there is double counting because (a, b) and (b, a) are counted twice. Therefore, print the value of ans/2 to get the required count.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > setArray;
map< int , int > mp;
void fillsetArray()
{
for ( int i = 1; i < 31; i++) {
setArray.push_back((1 << i) - 1);
}
}
int countPairs( int arr[], int n)
{
int ans = 0;
fillsetArray();
for ( int i = 0; i < n; i++)
mp[arr[i]]++;
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < 30; j++) {
int value = setArray[j] - arr[i];
ans += mp[value];
}
}
return ans / 2;
}
int main()
{
int arr[] = { 1, 2, 5, 10 };
int N = sizeof (arr) / sizeof (arr[0]);
cout << countPairs(arr, N);
return 0;
}
|
Java
import java.util.*;
class GFG{
static Vector<Integer> setArray =
new Vector<>();
static HashMap<Integer,
Integer> mp = new HashMap<Integer,
Integer>();
static void fillsetArray()
{
for ( int i = 1 ; i < 31 ; i++)
{
setArray.add(( 1 << i) - 1 );
}
}
static int countPairs( int arr[],
int n)
{
int ans = 0 ;
fillsetArray();
for ( int i = 0 ; i < n; i++)
if (mp.containsKey(arr[i]))
{
mp.put(arr[i],
mp.get(arr[i]) + 1 );
}
else
{
mp.put(arr[i], 1 );
}
for ( int i = 0 ; i < n; i++)
{
for ( int j = 0 ; j < 30 ; j++)
{
int value = setArray.get(j) -
arr[i];
if (mp.containsKey(value))
ans += mp.get(value);
}
}
return ans / 2 ;
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 5 , 10 };
int N = arr.length;
System.out.print(countPairs(arr, N));
}
}
|
Python3
from collections import defaultdict
setArray = []
mp = defaultdict ( int )
def fillsetArray():
for i in range ( 1 , 31 ):
setArray.append(( 1 << i) - 1 )
def countPairs(arr, n):
ans = 0
fillsetArray()
for i in range (n):
mp[arr[i]] + = 1
for i in range (n):
for j in range ( 30 ):
value = setArray[j] - arr[i]
ans + = mp[value]
return ans / / 2
if __name__ = = "__main__" :
arr = [ 1 , 2 , 5 , 10 ]
N = len (arr)
print (countPairs(arr, N))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static List< int > setArray = new List< int >();
static Dictionary< int ,
int > mp = new Dictionary< int ,
int >();
static void fillsetArray()
{
for ( int i = 1; i < 31; i++)
{
setArray.Add((1 << i) - 1);
}
}
static int countPairs( int []arr,
int n)
{
int ans = 0;
fillsetArray();
for ( int i = 0; i < n; i++)
if (mp.ContainsKey(arr[i]))
{
mp.Add(arr[i],
mp[arr[i]] + 1);
}
else
{
mp.Add(arr[i], 1);
}
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < 30; j++)
{
int value = setArray[j] -
arr[i];
if (mp.ContainsKey(value))
ans += mp[value];
}
}
return ans / 2;
}
public static void Main(String[] args)
{
int []arr = {1, 2, 5, 10};
int N = arr.Length;
Console.Write(countPairs(arr, N));
}
}
|
Javascript
<script>
let setArray = [];
let mp = new Map;
function fillsetArray()
{
for (let i = 1; i < 31; i++) {
setArray.push((1 << i) - 1);
}
return setArray;
}
function countPairs( arr, n)
{
let ans = 0;
setArray = fillsetArray();
for (let i = 0; i < n; i++){
if (mp[arr[i]])
mp[arr[i]]++;
else
mp[arr[i]] = 1
}
for (let i = 0; i < n; i++) {
for (let j = 0; j < 30; j++) {
let value = setArray[j] - arr[i];
if (mp[value])
ans += mp[value];
}
}
return Math.floor(ans / 2);
}
let Arr = [ 1, 2, 5, 10 ];
let N = Arr.length;
document.write(countPairs(Arr, N));
</script>
|
Time Complexity: O(N*32), where N is the size of the given array.
Auxiliary Space: O(N)
Last Updated :
26 Feb, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...