Найдите 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 pairs void 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 Code int 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 2 import java.util.*; class GFG{ static class _pair { int first, second; }; // Function to print the K // smallest pairs static 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 Code public 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
РЕКОМЕНДУЕМЫЕ СТАТЬИ |