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)

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.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of above approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to return the count of valid pairs
int countPairs(int a[], int n)
{
    // Storing occurrences of each element
    unordered_map<int, int> mp;
    for (int i = 0; i < n; i++)
        mp[a[i]]++;
  
    // Sort the array in deceasing order
    sort(a, a + n, greater<int>());
  
    // Start taking largest element each time
    int count = 0;
    for (int i = 0; i < n; i++) {
  
        // If element has already been paired
        if (mp[a[i]] < 1)
            continue;
  
        // Find the number which is greater than
        // a[i] and power of two
        int cur = 1;
        while (cur <= a[i])
            cur <<= 1;
  
        // If there is a number which adds up with a[i]
        // to form a power of two
        if (mp[cur - a[i]]) {
  
            // Edge case when a[i] and crr - a[i] is same
            // and we have only one occurrence of a[i] then
            // it cannot be paired
            if (cur - a[i] == a[i] and mp[a[i]] == 1)
                continue;
  
            count++;
  
            // Remove already paired elements
            mp[cur - a[i]]--;
            mp[a[i]]--;
        }
    }
  
    // Return the count
    return count;
}
  
// Driver code
int main()
{
    int a[] = { 3, 11, 14, 5, 13 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << countPairs(a, n);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of above approach
import java.util.TreeMap;
  
class Count
{
    // Function to return the count of valid pairs
    static int countPairs(int[] a, int n)
    {
  
        // To keep the element in sorted order
        TreeMap<Integer, Integer> map = new TreeMap<>();
        for (int i = 0; i < n; i++)
        {
            map.put(a[i], 1);
        }
          
        // Start taking largest element each time
        int count = 0;
        for (int i = 0; i < n; i++)
        {
            // If element has already been paired
            if (map.get(a[i]) < 1)
                continue;
  
            // Find the number which is greater than
            // a[i] and power of two
            int cur = 1;
            while (cur <= a[i])
                cur <<= 1;
  
            // If there is a number which adds up with a[i]
            // to form a power of two
            if (map.containsKey(cur - a[i]))
            {
                // Edge case when a[i] and crr - a[i] is same
                // and we have only one occurrence of a[i] then
                // it cannot be paired
                if (cur - a[i] == a[i] && map.get(a[i]) == 1)
                    continue;
                count++;
  
                // Remove already paired elements
                map.put(cur - a[i], map.get(cur - a[i]) - 1);
                map.put(a[i], map.get(a[i]) - 1);
            }
  
        }
        // Return the count
        return count;
    }
  
    // Driver code
    public static void main(String[] args) 
    {
        int[] a = { 3, 11, 14, 5, 13 };
        int n = a.length;
        System.out.println(countPairs(a, n));
    }
}
  
// This code is contributed by Vivekkumar Singh

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of above approach 
  
# Function to return the count 
# of valid pairs 
def countPairs(a, n) : 
  
    # Storing occurrences of each element 
    mp = dict.fromkeys(a, 0
    for i in range(n) : 
        mp[a[i]] += 1
  
    # Sort the array in deceasing order 
    a.sort(reverse = True)
      
    # Start taking largest element 
    # each time
    count = 0
    for i in range(n) : 
  
        # If element has already been paired 
        if (mp[a[i]] < 1) :
            continue
  
        # Find the number which is greater 
        # than a[i] and power of two 
        cur = 1
        while (cur <= a[i]) :
            cur = cur << 1
  
        # If there is a number which adds  
        # up with a[i] to form a power of two 
        if (cur - a[i] in mp.keys()) :
  
            # Edge case when a[i] and crr - a[i] 
            # is same and we have only one occurrence 
            # of a[i] then it cannot be paired 
            if (cur - a[i] == a[i] and mp[a[i]] == 1) :
                continue
  
            count += 1
  
            # Remove already paired elements 
            mp[cur - a[i]] -= 1
            mp[a[i]] -= 1
  
    # Return the count 
    return count 
  
# Driver code 
if __name__ == "__main__"
  
    a = [ 3, 11, 14, 5, 13
    n = len(a) 
    print(countPairs(a, n))
  
# This code is contributed by Ryuga

chevron_right


Output:

2

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

filter_none

edit
close

play_arrow

link
brightness_4
code

// Find the number which is greater than
// a[i] and power of two
int cur = 1;
while (cur <= a[i])
    cur <<= 1;

chevron_right


After optimizing above expression, time complexity of this solution becomes O(n Log n)



My Personal Notes arrow_drop_up

Dream it Do it

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.