Найдите k пар с наименьшими суммами в двух массивах | Комплект 2
Даны два массива arr1 [] и arr2 [], отсортированных в порядке возрастания, и целое число K. Задача состоит в том, чтобы найти k пар с наименьшими суммами таких, что один элемент пары принадлежит arr1 [], а другой элемент принадлежит arr2 [] . Размеры массивов могут быть разными. Предположим, что все элементы в каждом массиве различны.
Примеры:
Ввод: a1 [] = {1, 7, 11}
a2 [] = {2, 4, 6}
k = 3
Вывод: [1, 2], [1, 4], [1, 6]
Возвращаются первые 3 пары
из последовательности [1, 2], [1, 4], [1, 6], [7, 2],
[7, 4], [11, 2], [7, 6], [11, 4], [11, 6].
Ввод: a1 [] = {2, 3, 4}
a2 [] = {1, 6, 5, 8}
к = 4
Вывод: [1, 2] [1, 3] [1, 4] [2, 6]Здесь обсуждался подход с временной сложностью O (k * n1).
Эффективный подход: поскольку массив уже отсортирован. Приведенный ниже алгоритм может быть использован для решения этой проблемы:
- Идея состоит в том, чтобы поддерживать два указателя, один из которых указывает на одну пару в (a1, a2), а другой - на (a2, a1). Каждый раз сравнивайте суммы элементов, указанных двумя парами, и выведите минимальную. После этого увеличьте указатель на элемент в напечатанной паре, который был больше другого. Это помогает получить следующую возможную k наименьшую пару.
- После того, как указатель был обновлен до элемента, так что он снова начинает указывать на первый элемент массива, обновите другой указатель до следующего значения. Это обновление выполняется циклически.
- Кроме того, когда обе пары указывают на один и тот же элемент, обновите указатели в обеих парах, чтобы избежать печати дополнительной пары. Обновите указатель одной пары в соответствии с правилом 1, а другой - противоположным правилу 1. Это сделано для того, чтобы гарантировать, что все перестановки учтены и не будет повторений пар.
Ниже представлена работа алгоритма на примере 1:
a1[] = {1, 7, 11}, a2[] = {2, 4}, k = 3
Let the pairs of pointers be _one, _two
_one.first points to 1, _one.second points to 2 ;
_two.first points to 2, _two.second points to 1
1st pair:
Since _one and _two are pointing to same elements, print the pair once and update
- print [1, 2]
then update _one.first to 1, _one.second to 4 (following rule 1) ;
_two.first points to 2, _two.second points to 7 (opposite to rule 1).
If rule 1 was followed for both, then both of them would have been pointing to 1 and 4,
and it is not possible to get all possible permutations.
2nd pair:
Since a1[_one.first] + a2[_one.second] < a1[_two.second] + a2[_two.first], print them and update
- print [1, 4]
then update _one.first to 1, _one.second to 2
Since _one.second came to the first element of the array once again,
therefore _one.first points to 7
Repeat the above process for remaining K pairs
Below is the C++ implementation of the above approach:
C++
// C++ program to print the k smallest// pairs | Set 2#include <bits/stdc++.h>using namespace std;typedef struct _pair { int first, second;} _pair;// Function to print the K smallest pairsvoid printKPairs(int a1[], int a2[], int size1, int size2, int k){ // if k is greater than total pairs if (k > (size2 * size1)) { cout << "k pairs don"t exist
"; return; } // _pair _one keeps track of // "first" in a1 and "second" in a2 // in _two, _two.first keeps track of // element in the a2[] and _two.second in a1[] _pair _one, _two; _one.first = _one.second = _two.first = _two.second = 0; int cnt = 0; // Repeat the above process till // all K pairs are printed while (cnt < k) { // when both the pointers are pointing // to the same elements (point 3) if (_one.first == _two.second && _two.first == _one.second) { if (a1[_one.first] < a2[_one.second]) { cout << "[" << a1[_one.first] << ", " << a2[_one.second] << "] "; // updates according to step 1 _one.second = (_one.second + 1) % size2; if (_one.second == 0) // see point 2 _one.first = (_one.first + 1) % size1; // updates opposite to step 1 _two.second = (_two.second + 1) % size2; if (_two.second == 0) _two.first = (_two.first + 1) % size2; } else { cout << "[" << a2[_one.second] << ", " << a1[_one.first] << "] "; // updates according to rule 1 _one.first = (_one.first + 1) % size1; if (_one.first == 0) // see point 2 _one.second = (_one.second + 1) % size2; // updates opposite to rule 1 _two.first = (_two.first + 1) % size2; if (_two.first == 0) // see point 2 _two.second = (_two.second + 1) % size1; } } // else update as necessary (point 1) else if (a1[_one.first] + a2[_one.second] <= a2[_two.first] + a1[_two.second]) { if (a1[_one.first] < a2[_one.second]) { cout << "[" << a1[_one.first] << ", " << a2[_one.second] << "] "; // updating according to rule 1 _one.second = ((_one.second + 1) % size2); if (_one.second == 0) // see point 2 _one.first = (_one.first + 1) % size1; } else { cout << "[" << a2[_one.second] << ", " << a1[_one.first] << "] "; // updating according to rule 1 _one.first = ((_one.first + 1) % size1); if (_one.first == 0) // see point 2 _one.second = (_one.second + 1) % size2; } } else if (a1[_one.first] + a2[_one.second] > a2[_two.first] + a1[_two.second]) { if (a2[_two.first] < a1[_two.second]) { cout << "[" << a2[_two.first] << ", " << a1[_two.second] << "] "; // updating according to rule 1 _two.first = ((_two.first + 1) % size2); if (_two.first == 0) // see point 2 _two.second = (_two.second + 1) % size1; } else { cout << "[" << a1[_two.second] << ", " << a2[_two.first] << "] "; // updating according to rule 1 _two.second = ((_two.second + 1) % size1); if (_two.second == 0) // see point 2 _two.first = (_two.first + 1) % size1; } } cnt++; }}// Driver Codeint main(){ int a1[] = { 2, 3, 4 }; int a2[] = { 1, 6, 5, 8 }; int size1 = sizeof(a1) / sizeof(a1[0]); int size2 = sizeof(a2) / sizeof(a2[0]); int k = 4; printKPairs(a1, a2, size1, size2, k); return 0;} |
Java
// Java program to print// the k smallest pairs// | Set 2import java.util.*;class GFG{static class _pair{ int first, second;};// Function to print the K// smallest pairsstatic void printKPairs(int a1[], int a2[], int size1, int size2, int k){ // if k is greater than // total pairs if (k > (size2 * size1)) { System.out.print("k pairs don"t exist
"); return; } // _pair _one keeps track of // "first" in a1 and "second" in a2 // in _two, _two.first keeps track of // element in the a2[] and _two.second // in a1[] _pair _one = new _pair(); _pair _two = new _pair(); _one.first = _one.second = _two.first = _two.second = 0; int cnt = 0; // Repeat the above process // till all K pairs are printed while (cnt < k) { // when both the pointers are // pointing to the same elements // (point 3) if (_one.first == _two.second && _two.first == _one.second) { if (a1[_one.first] < a2[_one.second]) { System.out.print("[" + a1[_one.first] + ", " + a2[_one.second] + "] "); // updates according to step 1 _one.second = (_one.second + 1) % size2; // see point 2 if (_one.second == 0) _one.first = (_one.first + 1) % size1; // updates opposite to step 1 _two.second = (_two.second + 1) % size2; if (_two.second == 0) _two.first = (_two.first + 1) % size2; } else { System.out.print("[" + a2[_one.second] + ", " + a1[_one.first] + "] "); // updates according to rule 1 _one.first = (_one.first + 1) % size1; // see point 2 if (_one.first == 0) _one.second = (_one.second + 1) % size2; // updates opposite to rule 1 _two.first = (_two.first + 1) % size2; // see point 2 if (_two.first == 0) _two.second = (_two.second + 1) % size1; } } // else update as // necessary (point 1) else if (a1[_one.first] + a2[_one.second] <= a2[_two.first] + a1[_two.second]) { if (a1[_one.first] < a2[_one.second]) { System.out.print("[" + a1[_one.first] + ", " + a2[_one.second] + "] "); // updating according to rule 1 _one.second = ((_one.second + 1) % size2); // see point 2 if (_one.second == 0) _one.first = (_one.first + 1) % size1; } else { System.out.print("[" + a2[_one.second] + ", " + a1[_one.first] + "] "); // updating according to rule 1 _one.first = ((_one.first + 1) % size1); // see point 2 if (_one.first == 0) _one.second = (_one.second + 1) % size2; } } else if (a1[_one.first] + a2[_one.second] > a2[_two.first] + a1[_two.second]) { if (a2[_two.first] < a1[_two.second]) { System.out.print("[" + a2[_two.first] + ", " + a1[_two.second] + "] "); // updating according to rule 1 _two.first = ((_two.first + 1) % size2); // see point 2 if (_two.first == 0) _two.second = (_two.second + 1) % size1; } else { System.out.print("[" + a1[_two.second] + ", " + a2[_two.first] + "] "); // updating according to rule 1 _two.second = ((_two.second + 1) % size1); // see point 2 if (_two.second == 0) _two.first = (_two.first + 1) % size1; } } cnt++; }}// Driver Codepublic static void main(String[] args){ int a1[] = {2, 3, 4}; int a2[] = {1, 6, 5, 8}; int size1 = a1.length; int size2 = a2.length; int k = 4; printKPairs(a1, a2, size1, size2, k);}}// This code is contributed by gauravrajput1 |
Python3
# Pyth
РЕКОМЕНДУЕМЫЕ СТАТЬИ |