Número de pares cuya suma es una potencia de 2 – Part 1

Dada una array arr[] de enteros positivos, la tarea es contar el máximo número posible de pares (arr[i], arr[j]) tal que arr[i] + arr[j] sea una potencia de 2
Nota: Un elemento puede usarse como máximo una vez para formar un par.
Ejemplos: 
 

Entrada: arr[] = {3, 11, 14, 5, 13} 
Salida:
Todos los pares válidos son (13, 3) y (11, 5), ambos suman 16, que es una potencia de 2. 
Podríamos tener (3, 5) pero al hacerlo solo se pudo formar un máximo de 1 par. 
Por lo tanto, (3, 5) no es óptima.
Entrada: arr[] = {1, 2, 3} 
Salida:
1 y 3 se pueden emparejar para formar 4, que es una potencia de 2. 
 

Una solución simple es considerar cada par y verificar si la suma de este par es una potencia de 2 o no. La complejidad temporal de esta solución es O(n * n)
Un enfoque eficiente: es encontrar el elemento más grande de la array, digamos X , luego encontrar el elemento más grande del resto de los elementos de la array Y , de modo que Y ≤ X y X + Y sea una potencia de 2 Esta es una selección óptima de pares porque incluso si Y hace un par válido con algún otro elemento, digamos Z , entonces se dejará que Z se empareje con un elemento que no sea Y ( si es posible) para maximizar el número de pares válidos.
 

C++

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

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

<script>
 
// JavaScript Program to implement
// the above approach
 
    // Function to return the count of valid pairs
    function countPairs(a, n)
    {
 
        // To keep the element in sorted order
        let map = new Map();
        for (let i = 0; i < n; i++)
        {
            map.set(a[i], 1);
        }
         
        // Start taking largest element each time
        let count = 0;
        for (let 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
            let 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.has(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.set(cur - a[i], map.get(cur - a[i]) - 1);
                map.set(a[i], map.get(a[i]) - 1);
            }
 
        }
        // Return the count
        return count;
    }
 
// Driver Code
 
        let a = [ 3, 11, 14, 5, 13 ];
        let n = a.length;
        document.write(countPairs(a, n));
 
</script>
Producción: 

2

 

Tenga en cuenta que la operación a continuación en el código anterior se puede realizar en tiempo O (1) utilizando el último enfoque discutido en la potencia más pequeña de 2 mayor o igual que 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

Después de optimizar la expresión anterior, la complejidad temporal de esta solución se convierte en O(n Log n)
 

Publicación traducida automáticamente

Artículo escrito por aman0309 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *