📜  来自两个数组的 K 个最大和组合

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

给定两个相同大小的数组 (A, B) 和 N(两个数组的大小)。
总和组合是通过添加从数组A的一个元件和阵列B的另一元件从所有可能的组合和显示的最大K适用总和组合制成。

例子:

Input :  A[] : {3, 2} 
         B[] : {1, 4}
         K : 2 [Number of maximum sum
               combinations to be printed]
Output : 7    // (A : 3) + (B : 4)
         6    // (A : 2) + (B : 4)

Input :  A[] : {4, 2, 5, 1}
         B[] : {8, 0, 3, 5}
         K : 3
Output : 13   // (A : 5) + (B : 8)
         12   // (A : 4) + (B :  8)
         10   // (A : 2) + (B : 8)

方法 1(朴素算法):
我们可以通过从数组 A 中获取一个元素和从数组 B 中获取另一个元素并将它们插入到最大堆中的所有可能组合来使用蛮力。在最大堆中,最大元素位于根节点,因此每当我们从最大堆中弹出时,我们都会得到堆中存在的最大元素。插入所有和组合后,我们从最大堆中取出 K 个元素并显示它。
下面是上述方法的实现。

C++
// A simple C++ program to find N maximum
// combinations from two arrays,
#include 
using namespace std;
 
// function to display first N maximum sum
// combinations
void KMaxCombinations(int A[], int B[],
                      int N, int K)
{
    // max heap.
    priority_queue pq;
 
    // insert all the possible combinations
    // in max heap.
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            pq.push(A[i] + B[j]);
 
    // pop first N elements from max heap
    // and display them.
    int count = 0;
    while (count < K) {
        cout << pq.top() << endl;
        pq.pop();
        count++;
    }
}
 
// Driver Code.
int main()
{
    int A[] = { 4, 2, 5, 1 };
    int B[] = { 8, 0, 5, 3 };
    int N = sizeof(A) / sizeof(A[0]);
    int K = 3;
   
    // Function call
    KMaxCombinations(A, B, N, K);
    return 0;
}


Java
// Java program to find K
// maximum combinations
// from two arrays,
import java.io.*;
import java.util.*;
 
class GFG {
 
    // function to display first K
    // maximum sum combinations
    static void KMaxCombinations(int A[], int B[],
                                 int N, int K)
    {
        // max heap.
        PriorityQueue pq
            = new PriorityQueue(
                Collections.reverseOrder());
 
        // Insert all the possible
        // combinations in max heap.
        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)
                pq.add(A[i] + B[j]);
 
        // Pop first N elements
        // from max heap and
        // display them.
        int count = 0;
 
        while (count < K) {
            System.out.println(pq.peek());
            pq.remove();
            count++;
        }
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int A[] = { 4, 2, 5, 1 };
        int B[] = { 8, 0, 5, 3 };
        int N = A.length;
        int K = 3;
 
        // Function Call
        KMaxCombinations(A, B, N, K);
    }
}
 
// This code is contributed by Mayank Tyagi


Python 3
# Python program to find
# K maximum combinations
# from two arrays
import math
from queue import PriorityQueue
 
# Function to display first K
# maximum sum combinations
 
 
def KMaxCombinations(A, B, N, K):
 
    # Max heap.
    pq = PriorityQueue()
 
    # Insert all the possible
    # combinations in max heap.
    for i in range(0, N):
        for j in range(0, N):
            a = A[i] + B[j]
            pq.put((-a, a))
 
    # Pop first N elements from
    # max heap and display them.
    count = 0
    while (count < K):
        print(pq.get()[1])
        count = count + 1
 
 
# Driver method
A = [4, 2, 5, 1]
B = [8, 0, 5, 3]
N = len(A)
K = 3
 
# Function call
KMaxCombinations(A, B, N, K)
 
# This code is contributed
# by Gitanjali.


C#
// C# program to find K
// maximum combinations
// from two arrays,
using System;
using System.Collections.Generic;
public class GFG
{
 
  // function to display first K
  // maximum sum combinations
  static void KMaxCombinations(int []A, int []B,
                               int N, int K)
  {
 
    // max heap.
    List pq
      = new List();
 
    // Insert all the possible
    // combinations in max heap.
    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++)
        pq.Add(A[i] + B[j]);
 
    // Pop first N elements
    // from max heap and
    // display them.
    int count = 0;
    pq.Sort();
    pq.Reverse();
    while (count < K)
    {
      Console.WriteLine(pq[0]);
      pq.RemoveAt(0);
      count++;
    }
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
    int []A = { 4, 2, 5, 1 };
    int []B = { 8, 0, 5, 3 };
    int N = A.Length;
    int K = 3;
 
    // Function Call
    KMaxCombinations(A, B, N, K);
  }
}
 
// This code is contributed by Rajput-Ji


Javascript


CPP
// An efficient C++ program to find top K elements
// from two arrays.
#include 
using namespace std;
 
// Function prints k maximum possible combinations
void KMaxCombinations(vector& A,
                      vector& B, int K)
{
    // sort both arrays A and B
    sort(A.begin(), A.end());
    sort(B.begin(), B.end());
 
    int N = A.size();
 
    // Max heap which contains tuple of the format
    // (sum, (i, j)) i and j are the indices
    // of the elements from array A
    // and array B which make up the sum.
    priority_queue > > pq;
 
    // my_set is used to store the indices of
    // the  pair(i, j) we use my_set to make sure
    // the indices doe not repeat inside max heap.
    set > my_set;
 
    // initialize the heap with the maximum sum
    // combination ie (A[N - 1] + B[N - 1])
    // and also push indices (N - 1, N - 1) along
    // with sum.
    pq.push(make_pair(A[N - 1] + B[N - 1],
                      make_pair(N - 1, N - 1)));
 
    my_set.insert(make_pair(N - 1, N - 1));
 
    // iterate upto K
    for (int count = 0; count < K; count++)
    {
        // tuple format (sum, (i, j)).
        pair > temp = pq.top();
        pq.pop();
 
        cout << temp.first << endl;
 
        int i = temp.second.first;
        int j = temp.second.second;
 
        int sum = A[i - 1] + B[j];
 
        // insert (A[i - 1] + B[j], (i - 1, j))
        // into max heap.
        pair temp1 = make_pair(i - 1, j);
 
        // insert only if the pair (i - 1, j) is
        // not already present inside the map i.e.
        // no repeating pair should be present inside
        // the heap.
        if (my_set.find(temp1) == my_set.end())
        {
            pq.push(make_pair(sum, temp1));
            my_set.insert(temp1);
        }
 
        // insert (A[i] + B[j - 1], (i, j - 1))
        // into max heap.
        sum = A[i] + B[j - 1];
        temp1 = make_pair(i, j - 1);
 
        // insert only if the pair (i, j - 1)
        // is not present inside the heap.
        if (my_set.find(temp1) == my_set.end())
        {
            pq.push(make_pair(sum, temp1));
            my_set.insert(temp1);
        }
    }
}
 
// Driver Code.
int main()
{
    vector A = { 1, 4, 2, 3 };
    vector B = { 2, 5, 1, 6 };
    int K = 4;
   
    // Function call
    KMaxCombinations(A, B, K);
    return 0;
}


Java
// An efficient Java program to find
// top K elements from two arrays.
 
import java.io.*;
import java.util.*;
 
class GFG {
    public static void MaxPairSum(Integer[] A,
                                  Integer[] B,
                                  int N, int K)
    {
        // sort both arrays A and B
        Arrays.sort(A);
        Arrays.sort(B);
         
        // Max heap which contains Pair of
        // the format (sum, (i, j)) i and j are
        // the indices of the elements from
        // array A and array B which make up the sum.
        PriorityQueue sums
            = new PriorityQueue();
         
         // pairs is used to store the indices of
        // the  Pair(i, j) we use pairs to make sure
        // the indices doe not repeat inside max heap.
        HashSet pairs = new HashSet();
         
        // initialize the heap with the maximum sum
        // combination ie (A[N - 1] + B[N - 1])
        // and also push indices (N - 1, N - 1) along
        // with sum.
        int l = N - 1;
        int m = N - 1;
        pairs.add(new Pair(l, m));
        sums.add(new PairSum(A[l] + B[m], l, m));
         
        // iterate upto K
        for (int i = 0; i < K; i++)
        {
            // Poll the element from the
            // maxheap in theformat (sum, (l,m))
            PairSum max = sums.poll();
            System.out.println(max.sum);
            l = max.l - 1;
            m = max.m;
            // insert only if l and m are greater
            // than 0 and the pair (l, m) is
            // not already present inside set i.e.
            // no repeating pair should be
            // present inside the heap.
            if (l >= 0 && m >= 0
                && !pairs.contains(new Pair(l, m)))
            {
                // insert (A[l]+B[m], (l, m))
                // in the heap
                sums.add(new PairSum(A[l]
                         + B[m], l, m));
                pairs.add(new Pair(l, m));
            }
 
            l = max.l;
            m = max.m - 1;
 
            // insert only if l and m are
            // greater than 0 and
            // the pair (l, m) is not
            // already present inside
            // set i.e. no repeating pair
            // should be present
            // inside the heap.
            if (l >= 0 && m >= 0
                && !pairs.contains(new Pair(l, m)))
            {
                // insert (A[i1]+B[i2], (i1, i2))
                // in the heap
                sums.add(new PairSum(A[l]
                         + B[m], l, m));
                pairs.add(new Pair(l, m));
            }
        }
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        Integer A[] = { 1, 4, 2, 3 };
        Integer B[] = { 2, 5, 1, 6 };
        int N = A.length;
        int K = 4;
 
        // Function Call
        MaxPairSum(A, B, N, K);
    }
 
    public static class Pair {
 
        public Pair(int l, int m)
        {
            this.l = l;
            this.m = m;
        }
 
        int l;
        int m;
 
        @Override public boolean equals(Object o)
        {
            if (o == null) {
                return false;
            }
            if (!(o instanceof Pair)) {
                return false;
            }
            Pair obj = (Pair)o;
            return (l == obj.l && m == obj.m);
        }
 
        @Override public int hashCode()
        {
            return Objects.hash(l, m);
        }
    }
 
    public static class PairSum
        implements Comparable {
 
        public PairSum(int sum, int l, int m)
        {
            this.sum = sum;
            this.l = l;
            this.m = m;
        }
 
        int sum;
        int l;
        int m;
 
        @Override public int compareTo(PairSum o)
        {
            return Integer.compare(o.sum, sum);
        }
    }
}


输出
13
12
10

时间复杂度: O(N 2 )

方法 2(排序、最大堆、映射):
我们应该找到一种方法将我们的搜索空间限制为可能的候选和组合,而不是强行遍历所有可能的总和组合。

  1. 对数组数组 A 和数组 B 进行排序。
  2. 在 C++ 中创建一个最大堆,即 priority_queue 来存储总和组合以及组成总和的数组 A 和 B 中元素的索引。堆按总和排序。
  3. 使用最大可能的总和组合(即(A[N – 1] + B[N – 1],其中 N 是数组的大小)和来自两个数组的元素的索引(N – 1,N – 1)初始化堆.最大堆内的元组将是 (A[N-1] + B[N – 1], N – 1, N – 1)。堆按第一个值排序,即两个元素的总和。
  4. 弹出堆以获得当前最大的总和以及组成总和的元素的索引。令元组为 (sum, i, j)。
    1. 接下来将 (A[i – 1] + B[j], i – 1, j) 和 (A[i] + B[j – 1], i, j – 1) 插入到最大堆中,但要确保索引对即 (i – 1, j) 和 (i, j – 1) 不是
      已经存在于最大堆中。为了检查这一点,我们可以在 C++ 中使用 set。
    2. 回到 4 直到 K 次。

下面是上述方法的实现:

CPP

// An efficient C++ program to find top K elements
// from two arrays.
#include 
using namespace std;
 
// Function prints k maximum possible combinations
void KMaxCombinations(vector& A,
                      vector& B, int K)
{
    // sort both arrays A and B
    sort(A.begin(), A.end());
    sort(B.begin(), B.end());
 
    int N = A.size();
 
    // Max heap which contains tuple of the format
    // (sum, (i, j)) i and j are the indices
    // of the elements from array A
    // and array B which make up the sum.
    priority_queue > > pq;
 
    // my_set is used to store the indices of
    // the  pair(i, j) we use my_set to make sure
    // the indices doe not repeat inside max heap.
    set > my_set;
 
    // initialize the heap with the maximum sum
    // combination ie (A[N - 1] + B[N - 1])
    // and also push indices (N - 1, N - 1) along
    // with sum.
    pq.push(make_pair(A[N - 1] + B[N - 1],
                      make_pair(N - 1, N - 1)));
 
    my_set.insert(make_pair(N - 1, N - 1));
 
    // iterate upto K
    for (int count = 0; count < K; count++)
    {
        // tuple format (sum, (i, j)).
        pair > temp = pq.top();
        pq.pop();
 
        cout << temp.first << endl;
 
        int i = temp.second.first;
        int j = temp.second.second;
 
        int sum = A[i - 1] + B[j];
 
        // insert (A[i - 1] + B[j], (i - 1, j))
        // into max heap.
        pair temp1 = make_pair(i - 1, j);
 
        // insert only if the pair (i - 1, j) is
        // not already present inside the map i.e.
        // no repeating pair should be present inside
        // the heap.
        if (my_set.find(temp1) == my_set.end())
        {
            pq.push(make_pair(sum, temp1));
            my_set.insert(temp1);
        }
 
        // insert (A[i] + B[j - 1], (i, j - 1))
        // into max heap.
        sum = A[i] + B[j - 1];
        temp1 = make_pair(i, j - 1);
 
        // insert only if the pair (i, j - 1)
        // is not present inside the heap.
        if (my_set.find(temp1) == my_set.end())
        {
            pq.push(make_pair(sum, temp1));
            my_set.insert(temp1);
        }
    }
}
 
// Driver Code.
int main()
{
    vector A = { 1, 4, 2, 3 };
    vector B = { 2, 5, 1, 6 };
    int K = 4;
   
    // Function call
    KMaxCombinations(A, B, K);
    return 0;
}

Java

// An efficient Java program to find
// top K elements from two arrays.
 
import java.io.*;
import java.util.*;
 
class GFG {
    public static void MaxPairSum(Integer[] A,
                                  Integer[] B,
                                  int N, int K)
    {
        // sort both arrays A and B
        Arrays.sort(A);
        Arrays.sort(B);
         
        // Max heap which contains Pair of
        // the format (sum, (i, j)) i and j are
        // the indices of the elements from
        // array A and array B which make up the sum.
        PriorityQueue sums
            = new PriorityQueue();
         
         // pairs is used to store the indices of
        // the  Pair(i, j) we use pairs to make sure
        // the indices doe not repeat inside max heap.
        HashSet pairs = new HashSet();
         
        // initialize the heap with the maximum sum
        // combination ie (A[N - 1] + B[N - 1])
        // and also push indices (N - 1, N - 1) along
        // with sum.
        int l = N - 1;
        int m = N - 1;
        pairs.add(new Pair(l, m));
        sums.add(new PairSum(A[l] + B[m], l, m));
         
        // iterate upto K
        for (int i = 0; i < K; i++)
        {
            // Poll the element from the
            // maxheap in theformat (sum, (l,m))
            PairSum max = sums.poll();
            System.out.println(max.sum);
            l = max.l - 1;
            m = max.m;
            // insert only if l and m are greater
            // than 0 and the pair (l, m) is
            // not already present inside set i.e.
            // no repeating pair should be
            // present inside the heap.
            if (l >= 0 && m >= 0
                && !pairs.contains(new Pair(l, m)))
            {
                // insert (A[l]+B[m], (l, m))
                // in the heap
                sums.add(new PairSum(A[l]
                         + B[m], l, m));
                pairs.add(new Pair(l, m));
            }
 
            l = max.l;
            m = max.m - 1;
 
            // insert only if l and m are
            // greater than 0 and
            // the pair (l, m) is not
            // already present inside
            // set i.e. no repeating pair
            // should be present
            // inside the heap.
            if (l >= 0 && m >= 0
                && !pairs.contains(new Pair(l, m)))
            {
                // insert (A[i1]+B[i2], (i1, i2))
                // in the heap
                sums.add(new PairSum(A[l]
                         + B[m], l, m));
                pairs.add(new Pair(l, m));
            }
        }
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        Integer A[] = { 1, 4, 2, 3 };
        Integer B[] = { 2, 5, 1, 6 };
        int N = A.length;
        int K = 4;
 
        // Function Call
        MaxPairSum(A, B, N, K);
    }
 
    public static class Pair {
 
        public Pair(int l, int m)
        {
            this.l = l;
            this.m = m;
        }
 
        int l;
        int m;
 
        @Override public boolean equals(Object o)
        {
            if (o == null) {
                return false;
            }
            if (!(o instanceof Pair)) {
                return false;
            }
            Pair obj = (Pair)o;
            return (l == obj.l && m == obj.m);
        }
 
        @Override public int hashCode()
        {
            return Objects.hash(l, m);
        }
    }
 
    public static class PairSum
        implements Comparable {
 
        public PairSum(int sum, int l, int m)
        {
            this.sum = sum;
            this.l = l;
            this.m = m;
        }
 
        int sum;
        int l;
        int m;
 
        @Override public int compareTo(PairSum o)
        {
            return Integer.compare(o.sum, sum);
        }
    }
}
输出
10
9
9
8

时间复杂度: O(N log N) 假设 K <= N

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程