给定两个分别由大小分别为N和M的不同元素和整数K组成的整数数组arr []和brr [] ,任务是找到对(arr [i] , brr [j])的对数,使得(brr [j] – arr [i])>K。
例子:
Input: arr[] = {5, 9, 1, 8}, brr[] = {10, 12, 7, 4, 2, 3}, K = 3
Output: 6
Explanation:
Possible pairs that satisfy the given conditions are: {(5, 10), (5, 12), (1, 10), (1, 12), (1, 7), (8, 12)}.
Therefore, the required output is 6.
Input: arr[] = {2, 10}, brr[] = {5, 7}, K = 2
Output: 2
Explanation:
Possible pairs that satisfy the given conditions are: {(2, 5), (2, 7)}.
Therefore, the required output is 2.
天真的方法:有关解决此问题的最简单方法,请参阅本文的上一篇文章。
时间复杂度: O(N * M)
辅助空间: O(1)
两指针方法:有关此问题的两指针解决方案,请参阅本文的上一篇文章。
时间复杂度: O(N * log(N)+ M * log(M))
辅助空间: O(1)
高效的方法:想法是对较小的数组进行排序,并为每个元素遍历较大的数组,然后使用Binary Search在较小的数组中找到合适的元素进行配对。请按照以下步骤解决问题:
- 初始化变量计数以存储对的计数。
- 如果arr []的大小小于brr [] ,请执行以下操作。
- 对数组arr []排序并遍历数组brr []。
- 找到下界–在ARR(BRR [j]的K)[]因为其是小于BRR [j]的数目– K在ARR []将完全使一对与BRR [J]。
- 将下界索引与计数相加。
- 如果brr []的大小小于arr [] ,则执行以下操作。
- 对数组brr []排序并遍历arr [] 。
- 在brr []中找到(arr [i] + k)的上限,因为大于brr []中arr [i] + k的数字将与arr [i]完美配对。
- 将计数与(brr []的大小–上限索引)相加。
- 完成上述步骤后,将count的值打印为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to count pairs that satisfy
// the given conditions
int countPairs(int v1[], int v2[],
int n, int m, int k)
{
// Stores the count of pairs
int count = 0;
// If v1[] is smaller than v2[]
if (n <= m) {
// Sort the array v1[]
sort(v1, v1 + n);
// Traverse the array v2[]
for (int j = 0; j < m; j++) {
// Returns the address of
// the first number which
// is >= v2[j] - k
int index
= lower_bound(v1, v1 + n,
v2[j] - k)
- v1;
// Increase the count by all
// numbers less than v2[j] - k
count += index;
}
}
// Otherwise
else {
// Sort the array v2[]
sort(v2, v2 + m);
// Traverse the array v1[]
for (int i = 0; i < n; i++) {
// Returns the address of
// the first number which
// is > v1[i] + k
int index
= upper_bound(v2, v2 + m,
v1[i] + k)
- v2;
// Increase the count by all
// numbers greater than v1[i] + k
count += m - index;
}
}
// Return the total count of pairs
return count;
}
// Driver Code
int main()
{
int arr[] = { 5, 9, 1, 8 };
int brr[] = { 10, 12, 7, 4, 2, 3 };
int K = 3;
int N = sizeof(arr)
/ sizeof(arr[0]);
int M = sizeof(brr)
/ sizeof(brr[0]);
cout << countPairs(arr, brr,
N, M, K);
return 0;
}
Java
// Java program for the
// above approach
import java.util.*;
class GFG{
// Function to count pairs
// that satisfy the given
// conditions
static int countPairs(int v1[], int v2[],
int n, int m, int k)
{
// Stores the count of pairs
int count = 0;
// If v1[] is smaller than v2[]
if (n <= m)
{
// Sort the array v1[]
Arrays.sort(v1);
// Traverse the array v2[]
for (int j = 0; j < m; j++)
{
// Returns the address of
// the first number which
// is >= v2[j] - k
int index = lowerBound(v1, 0, n,
v2[j] - k);
// Increase the count by all
// numbers less than v2[j] - k
count += index;
}
}
// Otherwise
else
{
// Sort the array v2[]
Arrays.sort(v2);
// Traverse the array v1[]
for (int i = 0; i < n; i++)
{
// Returns the address of
// the first number which
// is > v1[i] + k
int index = upperBound(v2, 0, m,
v1[i] + k);
// Increase the count by all
// numbers greater than v1[i] + k
count += m - index;
}
}
// Return the total count of pairs
return count;
}
static int lowerBound(int[] a, int low,
int high, int element)
{
while(low < high)
{
int middle = low +
(high - low) / 2;
if(element > a[middle])
low = middle + 1;
else
high = middle;
}
return low;
}
static int upperBound(int[] a, int low,
int high, int element)
{
while(low < high)
{
int middle = low +
(high - low) / 2;
if(a[middle] > element)
high = middle;
else
low = middle + 1;
}
return low;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = {5, 9, 1, 8};
int brr[] = {10, 12, 7,
4, 2, 3};
int K = 3;
int N = arr.length;
int M = brr.length;
System.out.print(countPairs(arr, brr,
N, M, K));
}
}
// This code is contributed by shikhasingrajput
Python3
# Python3 program for the above approach
from bisect import bisect_left, bisect_right
# Function to count pairs that satisfy
# the given conditions
def countPairs(v1, v2, n, m, k):
# Stores the count of pairs
count = 0
# If v1[] is smaller than v2[]
if (n <= m):
# Sort the array v1[]
v1 = sorted(v1)
# Traverse the array v2[]
for j in range(m):
# Returns the address of
# the first number which
# is >= v2[j] - k
index = bisect_left(v1, v2[j] - k)
# Increase the count by all
# numbers less than v2[j] - k
count += index
# Otherwise
else:
# Sort the array v2[]
v2 = sorted(v2)
# Traverse the array v1[]
for i in range(n):
# Returns the address of
# the first number which
# is > v1[i] + k
index = bisect_right(v2, v1[i] + k)
# Increase the count by all
# numbers greater than v1[i] + k
count += m - index
# Return the total count of pairs
return count
# Driver Code
if __name__ == '__main__':
arr = [ 5, 9, 1, 8 ]
brr = [ 10, 12, 7, 4, 2, 3]
K = 3
N = len(arr)
M = len(brr)
print(countPairs(arr, brr, N, M, K))
# This code is contributed by mohit kumar 29
C#
// C# program for the
// above approach
using System;
class GFG{
// Function to count pairs
// that satisfy the given
// conditions
static int countPairs(int []v1, int []v2,
int n, int m, int k)
{
// Stores the count of pairs
int count = 0;
// If v1[] is smaller than v2[]
if (n <= m)
{
// Sort the array v1[]
Array.Sort(v1);
// Traverse the array v2[]
for (int j = 0; j < m; j++)
{
// Returns the address of
// the first number which
// is >= v2[j] - k
int index = lowerBound(v1, 0, n,
v2[j] - k);
// Increase the count by all
// numbers less than v2[j] - k
count += index;
}
}
// Otherwise
else
{
// Sort the array v2[]
Array.Sort(v2);
// Traverse the array v1[]
for (int i = 0; i < n; i++)
{
// Returns the address of
// the first number which
// is > v1[i] + k
int index = upperBound(v2, 0, m,
v1[i] + k);
// Increase the count by all
// numbers greater than v1[i] + k
count += m - index;
}
}
// Return the total count
// of pairs
return count;
}
static int lowerBound(int[] a, int low,
int high, int element)
{
while(low < high)
{
int middle = low +
(high - low) / 2;
if(element > a[middle])
low = middle + 1;
else
high = middle;
}
return low;
}
static int upperBound(int[] a, int low,
int high, int element)
{
while(low < high)
{
int middle = low +
(high - low) / 2;
if(a[middle] > element)
high = middle;
else
low = middle + 1;
}
return low;
}
// Driver Code
public static void Main(String[] args)
{
int []arr = {5, 9, 1, 8};
int []brr = {10, 12, 7,
4, 2, 3};
int K = 3;
int N = arr.Length;
int M = brr.Length;
Console.Write(countPairs(arr, brr,
N, M, K));
}
}
// This code is contributed by 29AjayKumar
6
时间复杂度: O((N + M)* min(log(N),log(M)))
辅助空间: O(1)