给定两个按升序排序的数组 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 最小对。
- 一旦指针更新到元素,使其再次开始指向数组的第一个元素,将另一个指针更新为下一个值。此更新是循环进行的。
- 此外,当两个对都指向同一个元素时,更新两个对中的指针以避免额外的对打印。根据规则 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
下面是上述方法的 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
Javascript
[1, 2] [1, 3] [1, 4] [2, 6]
时间复杂度:O(K)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。