📌  相关文章
📜  索引对的数量,使得第一个数组的元素对总和大于第二个数组

📅  最后修改于: 2021-10-26 07:01:12             🧑  作者: Mango

给定两个相等大小的整数数组A[]B[] ,任务是找到数组中索引对 {i, j} 的数量,使得A[i] + A[j] > B[i] + B[j]i < j
例子:

朴素的方法:朴素的方法是考虑给定数组中所有可能的 {i, j} 对,并检查是否A[i] + A[j] > B[i] + B[j] 。这可以通过使用嵌套循环的概念来完成。
时间复杂度: O(N 2 )
高效的方法:问题的关键观察是给定的条件也可以可视化为 (ai-bi) + (aj-bj)> 0 所以我们可以制作另一个数组来存储两个数组的差异。让这个数组为 D 。因此,问题简化为找到 Di+Dj>0 的对。现在我们可以对 D 数组进行排序,对于每个对应的元素 Di,我们将找到 Di 可以组成的好的对的数量,并将这个对的数量添加到一个计数变量中。对于每个元素 Di,找到好的对的数量,它可以使我们可以使用标准模板库的upper_bound函数求-Di的上界。由于数组已排序,因此 -Di 之后存在的所有元素也将与 Di 配对。因此,如果 -Di 的上限是 x 并且 n 是数组的总大小,则对应于 Di 的总对将为 nx。这种方法需要 O(NlogN) 时间。

  • 问题中的给定条件可以改写为:
A[i] + A[j] > B[i] + B[j]
A[i] + A[j] - B[i] - B[j] > 0
(A[i] - B[i]) + (A[j] - B[j]) > 0
  • 创建另一个数组,比如说 D,来存储两个数组中对应索引处的元素之间的差异,即
D[i] = A[i] - B[i]
  • 现在要确保满足约束 i < j,对差异数组 D 进行排序,以便每个元素 i 都小于其右侧的元素。
  • 如果在某个索引 i 处,差值数组 D 中的值是负数,那么我们只需要找到该值刚好大于-D[i]最近位置 ‘j’ ,这样求和后该值变为> 0 .
    为了找到这样的索引 ‘j’,可以使用 upper_bound()函数或二进制搜索,因为数组已排序。

下面是上述方法的实现:

C++
// C++ program to find the number of indices pair
// such that pair sum from first Array
// is greater than second Array
 
#include 
using namespace std;
 
// Function to get the number of pairs of indices
// {i, j} in the given two arrays A and B such that
// A[i] + A[j] > B[i] + B[j]
int getPairs(vector A, vector B, int n)
{
    // Intitializing the difference array D
    vector D(n);
 
    // Computing the difference between the
    // elements at every index and storing
    // it in the array D
    for (int i = 0; i < n; i++) {
        D[i] = A[i] - B[i];
    }
 
    // Sort the array D
    sort(D.begin(), D.end());
 
    // Variable to store the total
    // number of pairs that satisfy
    // the given condition
    long long total = 0;
 
    // Loop to iterate through the difference
    // array D and find the total number
    // of pairs of indices that follow the
    // given condition
    for (int i = n - 1; i >= 0; i--) {
 
        // If the value at the index i is positive,
        // then it remains positive for any pairs
        // with j such that j > i.
        if (D[i] > 0) {
            total += n - i - 1;
        }
 
        // If the value at that index is negative
        // then we need to find the index of the
        // value just greater than -D[i]
        else {
            int k = upper_bound(D.begin(),
                                D.end(), -D[i])
                    - D.begin();
            total += n - k;
        }
    }
    return total;
}
 
// Driver code
int main()
{
    int n = 5;
    vector A;
    vector B;
 
    A.push_back(4);
    A.push_back(8);
    A.push_back(2);
    A.push_back(6);
    A.push_back(2);
 
    B.push_back(4);
    B.push_back(5);
    B.push_back(4);
    B.push_back(1);
    B.push_back(3);
 
    cout << getPairs(A, B, n);
}


Java
// Java program to find the number of indices pair
// such that pair sum from first Array
// is greater than second Array
import java.util.*;
 
class GFG{
 
// Function to get the number of pairs of indices
// {i, j} in the given two arrays A and B such that
// A[i] + A[j] > B[i] + B[j]
static long getPairs(Vector A, Vector B, int n)
{
    // Intitializing the difference array D
    int []D = new int[n];
 
    // Computing the difference between the
    // elements at every index and storing
    // it in the array D
    for (int i = 0; i < n; i++)
    {
        D[i] = A.get(i) - B.get(i);
    }
 
    // Sort the array D
    Arrays.sort(D);
 
    // Variable to store the total
    // number of pairs that satisfy
    // the given condition
    long total = 0;
 
    // Loop to iterate through the difference
    // array D and find the total number
    // of pairs of indices that follow the
    // given condition
    for (int i = n - 1; i >= 0; i--) {
 
        // If the value at the index i is positive,
        // then it remains positive for any pairs
        // with j such that j > i.
        if (D[i] > 0) {
            total += n - i - 1;
        }
 
        // If the value at that index is negative
        // then we need to find the index of the
        // value just greater than -D[i]
        else {
            int k = upper_bound(D,0, D.length, -D[i]);
            total += n - k;
        }
    }
    return total;
}
static int upper_bound(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 n = 5;
    Vector A = new Vector();
    Vector B= new Vector();
 
    A.add(4);
    A.add(8);
    A.add(2);
    A.add(6);
    A.add(2);
 
    B.add(4);
    B.add(5);
    B.add(4);
    B.add(1);
    B.add(3);
 
    System.out.print(getPairs(A, B, n));
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python 3 program to find the number of indices pair
# such that pair sum from first Array
# is greater than second Array
import bisect
 
# Function to get the number of pairs of indices
# {i, j} in the given two arrays A and B such that
# A[i] + A[j] > B[i] + B[j]
def getPairs(A,  B, n):
 
    # Intitializing the difference array D
    D = [0]*(n)
  
    # Computing the difference between the
    # elements at every index and storing
    # it in the array D
    for i in range(n):
        D[i] = A[i] - B[i]
  
    # Sort the array D
    D.sort()
  
    # Variable to store the total
    # number of pairs that satisfy
    # the given condition
    total = 0
  
    # Loop to iterate through the difference
    # array D and find the total number
    # of pairs of indices that follow the
    # given condition
    for i in range(n - 1, -1, -1):
  
        # If the value at the index i is positive,
        # then it remains positive for any pairs
        # with j such that j > i.
        if (D[i] > 0):
            total += n - i - 1
  
        # If the value at that index is negative
        # then we need to find the index of the
        # value just greater than -D[i]
        else:
            k = bisect.bisect_right(D, -D[i], 0, len(D))
            total += n - k
    return total
  
# Driver code
if __name__ == "__main__":
     
    n = 5
    A = []
    B = []
  
    A.append(4);
    A.append(8);
    A.append(2);
    A.append(6);
    A.append(2);
  
    B.append(4);
    B.append(5);
    B.append(4);
    B.append(1);
    B.append(3);
  
    print(getPairs(A, B, n))
 
# This code is contributed by chitranayal


C#
// C# program to find the number of indices pair
// such that pair sum from first Array
// is greater than second Array
using System;
using System.Collections.Generic;
 
class GFG{
  
// Function to get the number of pairs of indices
// {i, j} in the given two arrays A and B such that
// A[i] + A[j] > B[i] + B[j]
static long getPairs(List A, List B, int n)
{
    // Intitializing the difference array D
    int []D = new int[n];
  
    // Computing the difference between the
    // elements at every index and storing
    // it in the array D
    for (int i = 0; i < n; i++)
    {
        D[i] = A[i] - B[i];
    }
  
    // Sort the array D
    Array.Sort(D);
  
    // Variable to store the total
    // number of pairs that satisfy
    // the given condition
    long total = 0;
  
    // Loop to iterate through the difference
    // array D and find the total number
    // of pairs of indices that follow the
    // given condition
    for (int i = n - 1; i >= 0; i--) {
  
        // If the value at the index i is positive,
        // then it remains positive for any pairs
        // with j such that j > i.
        if (D[i] > 0) {
            total += n - i - 1;
        }
  
        // If the value at that index is negative
        // then we need to find the index of the
        // value just greater than -D[i]
        else {
            int k = upper_bound(D,0, D.Length, -D[i]);
            total += n - k;
        }
    }
    return total;
}
static int upper_bound(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 n = 5;
    List A = new List();
    List B= new List();
  
    A.Add(4);
    A.Add(8);
    A.Add(2);
    A.Add(6);
    A.Add(2);
  
    B.Add(4);
    B.Add(5);
    B.Add(4);
    B.Add(1);
    B.Add(3);
  
    Console.Write(getPairs(A, B, n));
}
}
 
// This code is contributed by sapnasingh4991


Javascript


输出:
7

时间复杂度分析:

  • 数组的排序需要O(N * log(N))时间。
  • 找到刚好大于特定值的索引所花费的时间是O(Log(N)) 。由于在最坏的情况下,这可以对数组中的N 个元素执行,因此总时间复杂度为O(N * log(N))
  • 因此,整体时间复杂度为O(N * log(N))

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程