# Number of pairs whose sum is a power of 2

• Difficulty Level : Hard
• Last Updated : 16 Jun, 2022

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:
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 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++

 `// C++ implementation of above approach` `#include ` `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 decreasing 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;` `}`

## Java

 `// 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 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`

## Python3

 `# 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 decreasing 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`

## C#

 `// C# implementation of above approach` `using` `System;` `using` `System.Collections.Generic; `   `class` `GFG` `{` `    ``// Function to return the count of valid pairs` `    ``static` `int` `countPairs(``int``[] a, ``int` `n)` `    ``{`   `        ``// To keep the element in sorted order` `        ``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);` `        ``}` `        `  `        ``// Start taking largest element each time` `        ``int` `count = 0;` `        ``for` `(``int` `i = 0; i < n; i++)` `        ``{` `            ``// If element has already been paired` `            ``if` `(map[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[a[i]] == 1)` `                    ``continue``;` `                ``count++;`   `                ``// Remove already paired elements` `                ``map[cur - a[i]] = map[cur - a[i]] - 1;` `                ``map[a[i]] = map[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;` `        ``Console.WriteLine(countPairs(a, n));` `    ``}` `}`   `// This code is contributed by Princi Singh`

## Javascript

 ``

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

## C

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

## Javascript

 `// JavaScript program to find the ` `// number which is greater than` `// a[i] and power of two`     `var` `cur = 1;` `while` `(cur <= a[i])` `    ``cur <<= 1;`   `//This code is contributed by phasing17`

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

My Personal Notes arrow_drop_up
Recommended Articles
Page :