K maximum sum combinations from two arrays

Last Updated : 17 Oct, 2026

Given two integer arrays a[] and b[] of the same length, and an positive integer k, the goal is to find the top k maximum sum combinations, where each combination is formed by adding one element from a and one from b.
Each index from both arrays can be used at most once in a pair. Return the k largest sums in descending order.

Examples:

Input: a[] = [3, 2], b[] = [1, 4], k = 2
Output: [7, 6]
Explanation: Possible sums: 3 + 1 = 4, 3 + 4 = 7, 2 + 1 = 3, 2 + 4 = 6, Top 2 sums are 7 and 6.

Input: a[] = [1, 4, 2, 3], b[] = [2, 5, 1, 6], k = 3
Output: [10, 9, 9]
Explanation: The top 3 maximum possible sums are : 4 + 6 = 10, 3 + 6 = 9, and 4 + 5 = 9.

Try It Yourself
redirect icon

[Naive Approach] Generate All Combinations - O(n^2 × log (n^ 2)) Time and O(n^2) Space

The idea is to compute all possible sum combinations by pairing each element from array a[] with every element from array b[].

  • Since each element in a can form a pair with every element in b, we use a nested loop to generate all such sums.
  • After generating pair sums, we sort them in descending order and collect the top k values as the final result.
C++
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

vector<int> topKSumPairs(vector<int>& a, vector<int>& b, int k) {
    
    int n = a.size();
    
    // store all possible pair sums
    vector<int> allpossible;

    // generate all possible sums by pairing every 
    // element of 'a' with every element of 'b'
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            int currSum = a[i] + b[j];
            allpossible.push_back(currSum);
        }
    }
    
    // sort the sums in descending order to 
    // get the largest ones first
    sort(allpossible.begin(), allpossible.end(), greater<int>());

    // extract the top 'k' largest sums
    vector<int> res;
    for (int i = 0; i < k; i++) {
        res.push_back(allpossible[i]);
    }
    
    return res;
}

int main() {
    
    vector<int> a = {1, 4, 2, 3};
    vector<int> b = {2, 5, 1, 6};
    int k = 3;

    vector<int> res = topKSumPairs(a, b, k);

    for (int sum : res) {
        cout << sum << " ";
    }

    return 0;
}
Java
import java.util.ArrayList;
import java.util.Collections;

class GfG {
    public static ArrayList<Integer> topKSumPairs(int[] a, int[] b, int k) {

        int n = a.length;

        // store all possible pair sums
        ArrayList<Integer> allpossible = new ArrayList<>();

        // generate all possible sums by pairing every
        // element of 'a' with every element of 'b'
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                int currSum = a[i] + b[j];
                allpossible.add(currSum);
            }
        }

        // sort the sums in descending order to
        // get the largest ones first
        Collections.sort(allpossible, Collections.reverseOrder());

        // extract the top 'k' largest sums
        ArrayList<Integer> res = new ArrayList<>();
        for (int i = 0; i < k; i++) {
            res.add(allpossible.get(i));
        }

        return res;
    }

    public static void main(String[] args) {
        
        int[] a = {1, 4, 2, 3};
        int[] b = {2, 5, 1, 6};
        int k = 3;

        ArrayList<Integer> res = topKSumPairs(a, b, k);
        for (int sum : res) {
            System.out.print(sum + " ");
        }
    }
}
Python
def topKSumPairs(a, b, k):
    n = len(a)

    # store all possible pair sums
    allpossible = []

    # generate all possible sums by pairing every
    # element of 'a' with every element of 'b'
    for i in range(n):
        for j in range(n):
            currSum = a[i] + b[j]
            allpossible.append(currSum)

    # sort the sums in descending order to
    # get the largest ones first
    allpossible.sort(reverse=True)

    # extract the top 'k' largest sums
    res = []
    for i in range(k):
        res.append(allpossible[i])

    return res

if __name__ == "__main__":
    
    a = [1, 4, 2, 3]
    b = [2, 5, 1, 6]
    k = 3

    res = topKSumPairs(a, b, k)
    for sum in res:
        print(sum, end=" ")
C#
using System;
using System.Collections.Generic;

class GfG
{
    public static List<int> topKSumPairs(int[] a, int[] b, int k)
    {
        int n = a.Length;

        // Store all possible pair sums
        List<int> allpossible = new List<int>();

        // Generate all possible sums
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                int currSum = a[i] + b[j];
                allpossible.Add(currSum);
            }
        }

        // Sort in descending order
        allpossible.Sort((x, y) => y.CompareTo(x));

        // Extract top k sums
        List<int> res = new List<int>();

        for (int i = 0; i < k; i++)
        {
            res.Add(allpossible[i]);
        }

        return res;
    }

    public static void Main()
    {
        int[] a = { 1, 4, 2, 3 };
        int[] b = { 2, 5, 1, 6 };
        int k = 3;

        List<int> res = topKSumPairs(a, b, k);

        foreach (int sum in res)
        {
            Console.Write(sum + " ");
        }
    }
}
JavaScript
function topKSumPairs(a, b, k) {
    const n = a.length;

    // store all possible pair sums
    let allpossible = [];

    // generate all possible sums by pairing every
    // element of 'a' with every element of 'b'
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < n; j++) {
            let currSum = a[i] + b[j];
            allpossible.push(currSum);
        }
    }

    // sort the sums in descending order to
    // get the largest ones first
    allpossible.sort((x, y) => y - x);

    // extract the top 'k' largest sums
    let res = [];
    for (let i = 0; i < k; i++) {
        res.push(allpossible[i]);
    }

    return res;
}

// Driver Code
let a = [ 1, 4, 2, 3 ];
let b = [ 2, 5, 1, 6 ];
let k = 3;

let res = topKSumPairs(a, b, k);
console.log(res.join(" "));

Output
10 9 9 

[Better Approach] Heap-Based Top-K Pair Sum Approach - O(n^2 × log k) Time and O(k) Space

  • Generate all possible pair sums by adding each element from array a[] to each element from array b[].
  • A min-heap of size k is used to maintain the top k maximum sums. For every new pair sum, we insert it into the heap if it’s among the largest k seen so far.
  • We extract and reverse the heap to return the top k sums in descending order.
C++
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

vector<int> topKSumPairs(vector<int>& a, vector<int>& b, int k) {
    int n = a.size();

    // min-heap to keep track of the top k maximum pair sums
    priority_queue<int, vector<int>, greater<int>> minHeap;

    // generate all possible pair sums from a[i] + b[j]
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            int currSum = a[i] + b[j];

            // the heap has less than k elements, add the current sum
            if ((int)minHeap.size() < k) {
                minHeap.push(currSum);
            }
            // current sum is greater than the smallest in heap, replace it
            else if (currSum > minHeap.top()) {
                minHeap.pop();
                minHeap.push(currSum);
            }
        }
    }

    // extract elements from the heap and store in result
    vector<int> res;
    while (!minHeap.empty()) {
        res.push_back(minHeap.top());
        minHeap.pop();
    }

    // convert to descending order as required
    reverse(res.begin(), res.end());
    return res;
}

int main() {
    vector<int> a = {1, 4, 2, 3};
    vector<int> b = {2, 5, 1, 6};
    int k = 3;

    vector<int> res = topKSumPairs(a, b, k);

    for (int sum : res) {
        cout << sum << " ";
    }
    return 0;
}
Java
import java.util.PriorityQueue;
import java.util.Collections;
import java.util.ArrayList;

class GfG {
    public static ArrayList<Integer> topKSumPairs(int[] a, int[] b, int k) {
        int n = a.length;

        // min-heap to keep track of the top k maximum pair sums
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();

        // generate all possible pair sums from a[i] + b[j]
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                int currSum = a[i] + b[j];

                // the heap has less than k elements, add the current sum
                if (minHeap.size() < k) {
                    minHeap.offer(currSum);
                } 
                // current sum is greater than the smallest in heap, replace it
                else if (currSum > minHeap.peek()) {
                    minHeap.poll();
                    minHeap.offer(currSum);
                }
            }
        }

        // Extract elements from the heap and store in result
        ArrayList<Integer> res = new ArrayList<>();
        while (!minHeap.isEmpty()) {
            res.add(minHeap.poll());
        }

        // Convert to descending order as required
        Collections.reverse(res);
        return res;
    }

    public static void main(String[] args) {
        int[] a = {1, 4, 2, 3};
        int[] b = {2, 5, 1, 6};
        int k = 3;

        ArrayList<Integer> res = topKSumPairs(a, b, k);

        for (int sum : res) {
            System.out.print(sum + " ");
        }
    }
}
Python
import heapq

def topKSumPairs(a, b, k):
    n = len(a)
    
    # min-heap to keep track of the top k maximum pair sums
    minHeap = []

    # generate all possible pair sums from a[i] + b[j]
    for i in range(n):
        for j in range(n):
            currSum = a[i] + b[j]

            # the heap has less than k elements, add the current sum
            if len(minHeap) < k:
                heapq.heappush(minHeap, currSum)
            # current sum is greater than the smallest pair 
            # sum in the heap then replace it
            elif currSum > minHeap[0]:
                heapq.heappop(minHeap)
                heapq.heappush(minHeap, currSum)

    # extract elements from heap and store in result
    res = []
    while minHeap:
        res.append(heapq.heappop(minHeap))

    # convert to descending order as required
    res.reverse()
    return res

if __name__ == "__main__":
    a = [1, 4, 2, 3]
    b = [2, 5, 1, 6]
    k = 3

    res = topKSumPairs(a, b, k)
    print(" ".join(map(str, res)))
C#
using System;
using System.Collections.Generic;

class GfG {
    public static List<int> topKSumPairs(int[] a, int[] b, int k) {
        int n = a.Length;

        // Min-heap to keep track of top k largest pair sums
        SortedSet<(int sum, int index)> minHeap = new SortedSet<(int, int)>();
        int idx = 0;

        // Generate all possible pair sums
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                int currSum = a[i] + b[j];

                if (minHeap.Count < k) {
                    minHeap.Add((currSum, idx++));
                } 
                else {
                    // If current sum is greater than the smallest in heap
                    if (currSum > minHeap.Min.sum) {
                        minHeap.Remove(minHeap.Min);
                        minHeap.Add((currSum, idx++));
                    }
                }
            }
        }

        // Extract results and sort in descending order
        List<int> res = new List<int>();
        foreach (var pair in minHeap) {
            res.Add(pair.sum);
        }
        
        // Descending order
        res.Sort((x, y) => y.CompareTo(x)); 
        return res;
    }

    public static void Main() {
        int[] a = {1, 4, 2, 3};
        int[] b = {2, 5, 1, 6};
        int k = 3;

        List<int> res = topKSumPairs(a, b, k);
        foreach (int sum in res) {
            Console.Write(sum + " ");
        }
    }
}
JavaScript
function topKSumPairs(a, b, k) {
    let n = a.length;
    
    // min-heap to keep track of the top k maximum pair sums
    let minHeap = [];

    // generate all possible pair sums from a[i] + b[j]
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < n; j++) {
            let currSum = a[i] + b[j];

            // the heap has less than k elements, add the current sum
            if (minHeap.length < k) {
                minHeap.push(currSum);
                minHeap.sort((x, y) => x - y);
            } 
            // current sum is greater than the smallest pair 
            // sum in the heap then replace it
            else if (currSum > minHeap[0]) {
                minHeap.shift(); // remove smallest
                minHeap.push(currSum);
                minHeap.sort((x, y) => x - y);
            }
        }
    }

    // convert to descending order as required
    return minHeap.sort((a, b) => b - a);
}

// Driver Code
const a = [1, 4, 2, 3];
const b = [2, 5, 1, 6];
const k = 3;

const res = topKSumPairs(a, b, k);
console.log(res.join(" "));

Output
10 9 9 

[Expected Approach] Max Heap with Index Tracking - O(n × log n) Time and O(k) Space

The idea is to combine the largest elements from both arrays to form the highest possible sums.

  • Sort the arrays in descending order to ensure that the sum at indices (0, 0) is the maximum.
  • From this point, the next potential largest sums lie at positions (i+1, j) and (i, j+1) because of the sorted order. By exploring these candidates using a max heap and tracking visited index pairs, we efficiently gather the top k.

Steps by step approach:

  • Sort both arrays a[] and b[] in descending order to ensure the largest sums are considered first.
  • Initialize a max heap and insert the sum of the first elements (a[0] + b[0]) along with their indices (0, 0).
  • Use a set to track visited index pairs to prevent reprocessing the same combinations.
  • Repeat for k iterations by popping the largest sum from the heap and adding it to the result. Then, insert the next possible combinations (i+1, j) and (i, j+1) into the heap if they are within bounds and have not been visited.
C++
//Driver Code Starts
#include <iostream>
#include <vector>
#include <queue>
#include <set>
#include <algorithm>
using namespace std;

//Driver Code Ends

vector<int> topKSumPairs(vector<int> &a, vector<int> &b, int k) {
    
    int n = a.size();
    
    // sort both arrays in descending order
    sort(a.rbegin(), a.rend());
    sort(b.rbegin(), b.rend());

    // max-heap to store {sum, {i, j}}
    priority_queue<pair<int, pair<int, int>>> pq;
    set<pair<int, int>> vis;

    // start from the largest possible pair (0,0)
    pq.push({a[0] + b[0], {0, 0}});
    vis.insert({0, 0});

    vector<int> res;

    while (res.size() < k) {
        auto top = pq.top();
        pq.pop();

        int sum = top.first;
        int i = top.second.first;
        int j = top.second.second;

        res.push_back(sum);

        // add next element in a if not visited
        if (i + 1 < n && vis.find({i + 1, j}) == vis.end()) {
            pq.push({a[i + 1] + b[j], {i + 1, j}});
            vis.insert({i + 1, j});
        }

        // add next element in b if not visited
        if (j + 1 < n && vis.find({i, j + 1}) == vis.end()) {
            pq.push({a[i] + b[j + 1], {i, j + 1}});
            vis.insert({i, j + 1});
        }
    }


//Driver Code Starts
    return res;
}

int main() {

    vector<int> a = {1, 4, 2, 3};
    vector<int> b = {2, 5, 1, 6};
    int k = 3;

    vector<int> result = topKSumPairs(a, b, k);

    for (int sum : result) {
        cout << sum << " ";
    }
    return 0;
}
//Driver Code Ends
Java
//Driver Code Starts
import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
//Driver Code Ends

import java.util.HashSet;

class GfG {
    public static ArrayList<Integer> topKSumPairs(int[] a, int[] b, int k) {
        int n = a.length;

        // Sort both arrays in descending order
        Arrays.sort(a);
        Arrays.sort(b);
        reverse(a);
        reverse(b);

        // Max-heap to store {sum, i, j}
        PriorityQueue<int[]> pq = new PriorityQueue<>((x, y) -> y[0] - x[0]);
        HashSet<String> vis = new HashSet<>();

        // Start from the largest possible pair (0, 0)
        pq.offer(new int[]{a[0] + b[0], 0, 0});
        vis.add("0#0");

        ArrayList<Integer> res = new ArrayList<>();

        while (res.size() < k && !pq.isEmpty()) {
            int[] top = pq.poll();
            int sum = top[0], i = top[1], j = top[2];

            res.add(sum);

            // Try the next element in array a
            if (i + 1 < n && !vis.contains((i + 1) + "#" + j)) {
                pq.offer(new int[]{a[i + 1] + b[j], i + 1, j});
                vis.add((i + 1) + "#" + j);
            }

            // Try the next element in array b
            if (j + 1 < n && !vis.contains(i + "#" + (j + 1))) {
                pq.offer(new int[]{a[i] + b[j + 1], i, j + 1});
                vis.add(i + "#" + (j + 1));
            }
        }

//Driver Code Starts

        return res;
    }

    // Helper method to reverse an array in-place
    private static void reverse(int[] arr) {
        int l = 0, r = arr.length - 1;
        while (l < r) {
            int temp = arr[l];
            arr[l++] = arr[r];
            arr[r--] = temp;
        }
    }

    public static void main(String[] args) {
        int[] a = {1, 4, 2, 3};
        int[] b = {2, 5, 1, 6};
        int k = 3;

        ArrayList<Integer> result = topKSumPairs(a, b, k);
        for (int val : result) {
            System.out.print(val + " ");
        }
    }
}

//Driver Code Ends
Python
#Driver Code Starts
import heapq

#Driver Code Ends

def topKSumPairs(a, b, k):
    n = len(a)

    # sort both arrays in descending order
    a.sort(reverse=True)
    b.sort(reverse=True)

    visited = set()
    heap = []
    
    # max-heap to store {sum, {i, j}}
    heapq.heappush(heap, (-(a[0] + b[0]), 0, 0))
    
    # start from the largest possible pair (0,0)
    visited.add((0, 0))

    res = []

    while len(res) < k:
        sum_neg, i, j = heapq.heappop(heap)
        res.append(-sum_neg)
        
        # add next element in a if not visited
        if i + 1 < n and (i + 1, j) not in visited:
            heapq.heappush(heap, (-(a[i + 1] + b[j]), i + 1, j))
            visited.add((i + 1, j))
        
        # add next element in b if not visited
        if j + 1 < n and (i, j + 1) not in visited:
            heapq.heappush(heap, (-(a[i] + b[j + 1]), i, j + 1))
            visited.add((i, j + 1))

    return res

#Driver Code Starts

if __name__ == "__main__":
    a = [1, 4, 2, 3]
    b = [2, 5, 1, 6]
    k = 3

    result = topKSumPairs(a, b, k)
    print(" ".join(map(str, result)))

#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;

class GfG {
//Driver Code Ends

    public static List<int> topKSumPairs(int[] a, int[] b, int k) {
        int n = a.Length;

        // Sort both arrays in descending order
        Array.Sort(a);
        Array.Sort(b);
        Array.Reverse(a);
        Array.Reverse(b);

        // Max-heap: SortedSet stores (sum, i, j) sorted by descending sum
        var maxHeap = new SortedSet<(int, int, int)>(
            Comparer<(int, int, int)>.Create((x, y) =>
                x.Item1 != y.Item1 ? y.Item1.CompareTo(x.Item1) :
                x.Item2 != y.Item2 ? x.Item2.CompareTo(y.Item2) :
                x.Item3.CompareTo(y.Item3)
            )
        );

        var visited = new HashSet<(int, int)>();
        var result = new List<int>();

        // Add initial pair (0, 0)
        maxHeap.Add((a[0] + b[0], 0, 0));
        visited.Add((0, 0));

        while (result.Count < k && maxHeap.Count > 0) {
            var top = maxHeap.Min;
            maxHeap.Remove(top);

            int sum = top.Item1;
            int i = top.Item2, j = top.Item3;

            result.Add(sum);

            // Move to next element in a
            if (i + 1 < n && !visited.Contains((i + 1, j))) {
                maxHeap.Add((a[i + 1] + b[j], i + 1, j));
                visited.Add((i + 1, j));

//Driver Code Starts
            }

            // Move to next element in b
            if (j + 1 < n && !visited.Contains((i, j + 1))) {
                maxHeap.Add((a[i] + b[j + 1], i, j + 1));
                visited.Add((i, j + 1));
            }
        }

        return result;
    }

    public static void Main() {
        int[] a = {1, 4, 2, 3};
        int[] b = {2, 5, 1, 6};
        int k = 3;

        List<int> res = topKSumPairs(a, b, k);
        foreach (int sum in res) {
            Console.Write(sum + " ");
        }
    }
}

//Driver Code Ends
JavaScript
// Custom Max Heap implementation
class MaxHeap {
    constructor() {
        this.heap = [];
    }

    push(element) {
        this.heap.push(element);
        
        // Sort the heap to maintain max-heap property (descending order)
        this.heap.sort((a, b) => b[0] - a[0]);
    }

    pop() {
        return this.heap.shift();
    }

    size() {
        return this.heap.length;
    }
}

// Function to find top k maximum sum combinations
function topKSumPairs(a, b, k) {
    
    let n = a.length;
    
    // Sort both arrays in descending order
    a.sort((x, y) => y - x);
    b.sort((x, y) => y - x);

    const heap = new MaxHeap();
    const used = new Set();

    // Start from the largest pair (0, 0)
    heap.push([a[0] + b[0], 0, 0]);
    used.add(`0,0`);


//Driver Code Starts
    const res = [];

    // Extract top k combinations
    while (res.length < k) {
        const [sum, i, j] = heap.pop();
        res.push(sum);

        // Next element from a
        if (i + 1 < n && !used.has(`${i + 1},${j}`)) {
            heap.push([a[i + 1] + b[j], i + 1, j]);
            used.add(`${i + 1},${j}`);
        }

        // Next element from b
        if (j + 1 < n && !used.has(`${i},${j + 1}`)) {
            heap.push([a[i] + b[j + 1], i, j + 1]);
            used.add(`${i},${j + 1}`);
        }
    }

    return res;
}

// Driver Code
const k = 3;
const a = [1, 4, 2, 3];
const b = [2, 5, 1, 6];

const result = topKSumPairs(a, b, k);
console.log(result.join(" "));

//Driver Code Ends

Output
10 9 9 


Comment