📜  总和为 2 的幂的对数

📅  最后修改于: 2021-10-28 01:34:38             🧑  作者: Mango

给定一个由正整数组成的数组arr[] ,任务是计算对(arr[i], arr[j])的最大可能数量,使得arr[i] + arr[j]2
注意:一个元素最多可以使用一次以形成一对。
例子:

一个简单的解决方案是考虑每一对并检查这对的总和是否是 2 的幂。此解决方案的时间复杂度为 O(n * n)
一种有效的方法:是从数组中找到最大的元素,比如X,然后从数组的其余元素Y 中找到最大的元素,使得Y ≤ X并且X + Y2。这是对的最佳选择,因为即使Y与其他元素(例如Z)形成有效对,那么Z将与Y以外的元素配对(如果可能)以最大化有效对的数量。

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 mp;
    for (int i = 0; i < n; i++)
        mp[a[i]]++;
 
    // Sort the array in deceasing order
    sort(a, a + n, greater());
 
    // 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 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


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 map = new Dictionary();
        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


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


输出:

2

请注意,上面代码中的以下操作可以使用大于或等于 n 的 2 的最小幂中讨论的最后一种方法在 O(1) 时间内完成

C

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

优化上述表达式后,该解的时间复杂度变为 O(n Log n)

想要从精选的视频和练习题中学习,请查看C++ 基础课程,从基础到高级 C++ 和C++ STL 课程,了解语言和 STL。要完成从学习语言到 DS Algo 等的准备工作,请参阅完整的面试准备课程