给定两个数组arr1 []和arr2 []以升序排序,并且整数K。任务是找到具有最小总和的k对,以使对中的一个元素属于arr1 [],另一个元素属于arr2 [] 。数组的大小可能不同。假设所有元素在每个数组中都是不同的。
例子:
Input: a1[] = {1, 7, 11}
a2[] = {2, 4, 6}
k = 3
Output: [1, 2], [1, 4], [1, 6]
The first 3 pairs are returned
from the sequence [1, 2], [1, 4], [1, 6], [7, 2],
[7, 4], [11, 2], [7, 6], [11, 4], [11, 6].
Input: a1[] = { 2, 3, 4 }
a2[] = { 1, 6, 5, 8 }
k = 4
Output: [1, 2] [1, 3] [1, 4] [2, 6]
这里讨论了一种具有时间复杂度O(k * n1)的方法。
高效的方法:由于数组已经排序。可以使用下面给出的算法来解决此问题:
- 这个想法是要维护两个指针,一个指针指向(a1,a2)中的一对,另一个指向(a2,a1)中的另一个。每次比较两个对所指向的元素之和,并打印最小的对。此后,将指针增加到打印对中大于另一个的元素的指针。这有助于获得下一个可能的k个最小的对。
- 一旦指针已更新到该元素,使其开始再次指向数组的第一个元素,则将另一个指针更新为下一个值。此更新是周期性进行的。
- 另外,当两对都指向同一元素时,请更新两对中的指针,以避免打印多余的对。根据rule1更新一对指针,而与rule1相反的另一对则更新。这样做是为了确保考虑所有排列,并且没有重复的对。
下面是算法的工作示例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
以下是上述方法的C++实现:
C++
// C++ program to print the k smallest
// pairs | Set 2
#include
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\n";
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\n");
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
# Python3 program to print the k smallest
# pairs | Set 2
# Function to print the K smallest pairs
def printKPairs(a1, a,size1, size2, k):
# if k is greater than total pairs
if (k > (size2 * size1)):
print("k pairs don't exist\n")
return
# _pair _one keeps track of
# 'first' in a1 and 'second' in a2
# in _two, _two[0] keeps track of
# element in the a2and _two[1] in a1[]
_one, _two = [0, 0], [0, 0]
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 (po3)
if (_one[0] == _two[1]
and _two[0] == _one[1]):
if (a1[_one[0]] < a2[_one[1]]):
print("[", a1[_one[0]], ", ",
a2[_one[1]],"] ", end=" ")
# updates according to step 1
_one[1] = (_one[1] + 1) % size2
if (_one[1] == 0): #see po2
_one[0] = (_one[0] + 1) % size1
# updates opposite to step 1
_two[1] = (_two[1] + 1) % size2
if (_two[1] == 0):
_two[0] = (_two[0] + 1) % size2
else:
print("[",a2[_one[1]]
,", ",a1[_one[0]],"] ",end=" ")
# updates according to rule 1
_one[0] = (_one[0] + 1) % size1
if (_one[0] == 0): #see po2
_one[1] = (_one[1] + 1) % size2
# updates opposite to rule 1
_two[0] = (_two[0] + 1) % size2
if (_two[0] == 0): #see po2
_two[1] = (_two[1] + 1) % size1
# else update as necessary (po1)
elif (a1[_one[0]] + a2[_one[1]]
<= a2[_two[0]] + a1[_two[1]]):
if (a1[_one[0]] < a2[_one[1]]):
print("[",a1[_one[0]],", ",
a2[_one[1]],"] ",end=" ")
# updating according to rule 1
_one[1] = ((_one[1] + 1) % size2)
if (_one[1] == 0): # see po2
_one[0] = (_one[0] + 1) % size1
else:
print("[",a2[_one[1]],", ",
a1[_one[0]],"] ", end=" ")
# updating according to rule 1
_one[0] = ((_one[0] + 1) % size1)
if (_one[0] == 0): # see po2
_one[1] = (_one[1] + 1) % size2
elif (a1[_one[0]] + a2[_one[1]]
> a2[_two[0]] + a1[_two[1]]):
if (a2[_two[0]] < a1[_two[1]]):
print("[",a2[_two[0]],", ",a1[_two[1]],"] ",end=" ")
# updating according to rule 1
_two[0] = ((_two[0] + 1) % size2)
if (_two[0] == 0): #see po2
_two[1] = (_two[1] + 1) % size1
else:
print("[",a1[_two[1]]
,", ",a2[_two[0]],"] ",end=" ")
# updating according to rule 1
_two[1] = ((_two[1] + 1) % size1)
if (_two[1] == 0): #see po2
_two[0] = (_two[0] + 1) % size1
cnt += 1
# Driver Code
if __name__ == '__main__':
a1= [2, 3, 4]
a2= [1, 6, 5, 8]
size1 = len(a1)
size2 = len(a2)
k = 4
printKPairs(a1, a2, size1, size2, k)
# This code is contributed by mohit kumar 29
C#
// C# program to print
// the k smallest pairs
// | Set 2
using System;
class GFG{
public class _pair
{
public 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))
{
Console.Write("k pairs don't exist\n");
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])
{
Console.Write("[" + 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
{
Console.Write("[" + 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])
{
Console.Write("[" + 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
{
Console.Write("[" + 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])
{
Console.Write("[" + 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 {
Console.Write("[" + 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
[1, 2] [1, 3] [1, 4] [2, 6]
时间复杂度:O(K)