Number of pairs whose sum is a power of 2
Given an array arr[] of positive integers, the task is to count the maximum possible number of pairs (arr[i], arr[j]) such that arr[i] + arr[j] is a power of 2.
Note: One element can be used at most once to form a pair.
Examples:
Input: arr[] = {3, 11, 14, 5, 13}
Output: 2
All valid pairs are (13, 3) and (11, 5) both sum up to 16 which is a power of 2.
We could have used (3, 5) but by doing so maximum of 1 pair could only be formed.
Therefore, (3, 5) is not optimal.
Input: arr[] = {1, 2, 3}
Output: 1
1 and 3 can be paired to form 4, which is a power of 2.
A simple solution is to consider every pair and check if sum of this pair is a power of 2 or not. Time Complexity of this solution is O(n * n).
Auxiliary Space: O(1)
An Efficient Approach: is to find the largest element from the array say X then find the largest element from the rest of the array elements Y such that Y ? X and X + Y is a power of 2. This is an optimal selection of pair because even if Y makes a valid pair with some other element say Z then Z will be left to pair with an element other than Y (if possible) to maximize the number of valid pairs.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int countPairs( int a[], int n)
{
unordered_map< int , int > mp;
for ( int i = 0; i < n; i++)
mp[a[i]]++;
sort(a, a + n, greater< int >());
int count = 0;
for ( int i = 0; i < n; i++) {
if (mp[a[i]] < 1)
continue ;
int cur = 1;
while (cur <= a[i])
cur <<= 1;
if (mp[cur - a[i]]) {
if (cur - a[i] == a[i] and mp[a[i]] == 1)
continue ;
count++;
mp[cur - a[i]]--;
mp[a[i]]--;
}
}
return count;
}
int main()
{
int a[] = { 3, 11, 14, 5, 13 };
int n = sizeof (a) / sizeof (a[0]);
cout << countPairs(a, n);
return 0;
}
|
Java
import java.util.TreeMap;
class Count
{
static int countPairs( int [] a, int n)
{
TreeMap<Integer, Integer> map = new TreeMap<>();
for ( int i = 0 ; i < n; i++)
{
map.put(a[i], 1 );
}
int count = 0 ;
for ( int i = 0 ; i < n; i++)
{
if (map.get(a[i]) < 1 )
continue ;
int cur = 1 ;
while (cur <= a[i])
cur <<= 1 ;
if (map.containsKey(cur - a[i]))
{
if (cur - a[i] == a[i] && map.get(a[i]) == 1 )
continue ;
count++;
map.put(cur - a[i], map.get(cur - a[i]) - 1 );
map.put(a[i], map.get(a[i]) - 1 );
}
}
return count;
}
public static void main(String[] args)
{
int [] a = { 3 , 11 , 14 , 5 , 13 };
int n = a.length;
System.out.println(countPairs(a, n));
}
}
|
Python3
def countPairs(a, n) :
mp = dict .fromkeys(a, 0 )
for i in range (n) :
mp[a[i]] + = 1
a.sort(reverse = True )
count = 0
for i in range (n) :
if (mp[a[i]] < 1 ) :
continue
cur = 1
while (cur < = a[i]) :
cur = cur << 1
if (cur - a[i] in mp.keys()) :
if (cur - a[i] = = a[i] and mp[a[i]] = = 1 ) :
continue
count + = 1
mp[cur - a[i]] - = 1
mp[a[i]] - = 1
return count
if __name__ = = "__main__" :
a = [ 3 , 11 , 14 , 5 , 13 ]
n = len (a)
print (countPairs(a, n))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int countPairs( int [] a, int n)
{
Dictionary< int ,
int > map = new Dictionary< int ,
int >();
for ( int i = 0; i < n; i++)
{
if (!map.ContainsKey(a[i]))
map.Add(a[i], 1);
}
int count = 0;
for ( int i = 0; i < n; i++)
{
if (map[a[i]] < 1)
continue ;
int cur = 1;
while (cur <= a[i])
cur <<= 1;
if (map.ContainsKey(cur - a[i]))
{
if (cur - a[i] == a[i] && map[a[i]] == 1)
continue ;
count++;
map[cur - a[i]] = map[cur - a[i]] - 1;
map[a[i]] = map[a[i]] - 1;
}
}
return count;
}
public static void Main(String[] args)
{
int [] a = { 3, 11, 14, 5, 13 };
int n = a.Length;
Console.WriteLine(countPairs(a, n));
}
}
|
Javascript
<script>
function countPairs(a, n)
{
let map = new Map();
for (let i = 0; i < n; i++)
{
map.set(a[i], 1);
}
let count = 0;
for (let i = 0; i < n; i++)
{
if (map.get(a[i]) < 1)
continue ;
let cur = 1;
while (cur <= a[i])
cur <<= 1;
if (map.has(cur - a[i]))
{
if (cur - a[i] == a[i] && map.get(a[i]) == 1)
continue ;
count++;
map.set(cur - a[i], map.get(cur - a[i]) - 1);
map.set(a[i], map.get(a[i]) - 1);
}
}
return count;
}
let a = [ 3, 11, 14, 5, 13 ];
let n = a.length;
document.write(countPairs(a, n));
</script>
|
Note that the below operation in above code can be done in O(1) time using the last approach discussed in Smallest power of 2 greater than or equal to n
C
int cur = 1;
while (cur <= a[i])
cur <<= 1;
|
C++
int cur = 1;
while (cur <= a[i])
cur <<= 1;
|
Java
int cur = 1 ;
while (cur <= a[i])
cur <<= 1 ;
|
Python
cur = 1
while (cur < = a[i]):
cur = cur << 1
|
C#
int cur = 1;
while (cur <= a[i])
cur <<= 1;
|
Javascript
var cur = 1;
while (cur <= a[i])
cur <<= 1;
|
After optimizing above expression, time complexity of this solution becomes O(n Log n)
Auxiliary Space: O(n)
Last Updated :
25 Nov, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...