给定两个整数数组arr[]和brr[] 分别由大小为N和M的不同元素和一个整数K 组成,任务是找到对(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)
高效的方法:想法是对较小的数组进行排序,并为每个元素遍历较大的数组,在较小的数组中找到合适的元素进行配对,使用二分搜索。请按照以下步骤解决问题:
- 初始化一个变量count来存储对的计数。
- 如果arr[]大小小于brr[] ,则执行以下操作。
- 对数组arr[] 进行排序并遍历数组brr[]。
- 在arr[] 中找到(brr[j] – k)的下界,因为在arr[]中小于brr[j] – k的数字将与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
Javascript
6
时间复杂度: O((N+M) * min(log(N), log(M)))
辅助空间: O(1)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live