📌  相关文章
📜  从给定数组中计数其乘积在给定范围内的对

📅  最后修改于: 2022-05-13 01:56:09.965000             🧑  作者: Mango

从给定数组中计数其乘积在给定范围内的对

给定一个大小为N的数组arr[]以及整数LR ,任务是计算对[arr i , arr j ]的数量,使得i < jarr[i] * arr[j]的乘积 位于给定范围[L, R]内,即L ≤ arr[i] * arr[j] ≤ R。

例子:

朴素方法:解决问题的最简单方法是从数组中生成所有可能的对,并为每一对检查其乘积是否在[L, R]范围内。

时间复杂度: O(N 2 )
辅助空间: O(1)

有效的方法:这个问题可以通过排序和二分搜索技术来解决。请按照以下步骤解决此问题:

  • 对数组arr[] 进行排序。
  • 初始化一个变量,比如ans0,以存储乘积在[L, R] 范围内的对数。
  • 使用变量i遍历范围[0, N-1]并执行以下步骤
    • 找到一个元素的上界,使得该元素小于等于R / arr[i]。
    • 找到一个元素的下界,使得该元素大于或等于L / arr[i]。
    • 上限 - 下限添加到ans
  • 完成上述步骤后,打印ans

下面是上述方法的实现。

C++
// C++ program for above approach
 
#include 
using namespace std;
 
// Function to count pairs from an array
// whose product lies in the range [l, r]
void countPairs(int arr[], int l,
                int r, int n)
{
    // Sort the array arr[]
    sort(arr, arr + n);
 
    // Stores the final answer
    int ans = 0;
 
    for (int i = 0; i < n; i++) {
 
        // Upper Bound for arr[j] such
        // that arr[j] <= r/arr[i]
        auto itr1 = upper_bound(
                        arr + i + 1,
                        arr + n, r / arr[i])
                    - arr;
 
        // Lower Bound for arr[j] such
        // that arr[j] >= l/arr[i]
        auto itr2 = lower_bound(
                        arr + i + 1, arr + n,
                        ceil(double(l) / double(arr[i])))
                    - arr;
 
        ans += itr1 - itr2;
    }
 
    // Print the answer
    cout << ans << endl;
}
 
// Driver Code
int main()
{
    // Given Input
    int arr[] = { 2,2 };
    int l = 5, r = 9;
 
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    countPairs(arr, l, r, n);
 
    return 0;
}


Java
// Java program for above approach
import java.util.Arrays;
 
class GFG{
     
// Function to count pairs from an array
// whose product lies in the range [l, r]
public static void countPairs(int[] arr, int l,
                              int r, int n)
{
     
    // Sort the array arr[]
    Arrays.sort(arr);
 
    // Stores the final answer
    int ans = 0;
 
    for(int i = 0; i < n; i++)
    {
         
        // Upper Bound for arr[j] such
        // that arr[j] <= r/arr[i]
        int itr1 = upper_bound(arr, 0, arr.length - 1,
                               l / arr[i]);
 
        // Lower Bound for arr[j] such
        // that arr[j] >= l/arr[i]
        int itr2 = lower_bound(arr, 0, arr.length - 1,
                               l / arr[i]);
        ans += itr1 - itr2;
    }
 
    // Print the answer
    System.out.println(ans);
}
 
public static int lower_bound(int[] arr, int low,
                              int high, int X)
{
     
    // Base Case
    if (low > high)
    {
        return low;
    }
 
    // Find the middle index
    int mid = low + (high - low) / 2;
 
    // If arr[mid] is greater than
    // or equal to X then search
    // in left subarray
    if (arr[mid] >= X)
    {
        return lower_bound(arr, low, mid - 1, X);
    }
 
    // If arr[mid] is less than X
    // then search in right subarray
    return lower_bound(arr, mid + 1, high, X);
}
 
public static int upper_bound(int[] arr, int low,
                              int high, int X)
{
     
    // Base Case
    if (low > high)
        return low;
 
    // Find the middle index
    int mid = low + (high - low) / 2;
 
    // If arr[mid] is less than
    // or equal to X search in
    // right subarray
    if (arr[mid] <= X)
    {
        return upper_bound(arr, mid + 1, high, X);
    }
 
    // If arr[mid] is greater than X
    // then search in left subarray
    return upper_bound(arr, low, mid - 1, X);
}
 
// Driver Code
public static void main(String args[])
{
     
    // Given Input
    int[] arr = { 4, 1, 2, 5 };
    int l = 4, r = 9;
    int n = arr.length;
 
    // Function Call
    countPairs(arr, l, r, n);
}
}
 
// This code is contributed by gfgking.


Python3
# Python program for above approach
 
# Function to count pairs from an array
# whose product lies in the range [l, r]
def countPairs(arr, l, r, n):
 
    # Sort the array arr[]
    arr[::-1]
 
    # Stores the final answer
    ans = 0;
 
    for i in range(n):
 
        # Upper Bound for arr[j] such
        # that arr[j] <= r/arr[i]
        itr1 = upper_bound(arr, 0, len(arr) - 1, l // arr[i])
 
        # Lower Bound for arr[j] such
        # that arr[j] >= l/arr[i]
        itr2 = lower_bound(arr, 0, len(arr) - 1, l // arr[i]);
 
        ans += itr1 - itr2;
 
    # Print the answer
    print(ans);
 
def lower_bound(arr, low, high, X):
 
    # Base Case
    if (low > high):
        return low;
 
    # Find the middle index
    mid = low + (high - low) // 2;
 
    # If arr[mid] is greater than
    # or equal to X then search
    # in left subarray
    if (arr[mid] >= X):
        return lower_bound(arr, low, mid - 1, X);
 
    # If arr[mid] is less than X
    # then search in right subarray
    return lower_bound(arr, mid + 1, high, X);
 
def upper_bound(arr, low, high, X):
 
    # Base Case
    if (low > high):
        return low;
 
    # Find the middle index
    mid = low + (high - low) // 2;
 
    # If arr[mid] is less than
    # or equal to X search in
    # right subarray
    if (arr[mid] <= X):
        return upper_bound(arr, mid + 1, high, X);
 
    # If arr[mid] is greater than X
    # then search in left subarray
    return upper_bound(arr, low, mid - 1, X);
 
 
# Driver Code
 
# Given Input
arr = [4, 1, 2, 5];
l = 4;
r = 9;
 
n = len(arr)
 
# Function Call
countPairs(arr, l, r, n);
 
# This code is contributed by _Saurabh_Jaiswal.


C#
// C# program for the above approach
using System;
 
class GFG{
 
// Function to count pairs from an array
// whose product lies in the range [l, r]
public static void countPairs(int[] arr, int l,
                              int r, int n)
{
     
    // Sort the array arr[]
    Array.Sort(arr);
  
    // Stores the final answer
    int ans = 0;
  
    for(int i = 0; i < n; i++)
    {
         
        // Upper Bound for arr[j] such
        // that arr[j] <= r/arr[i]
        int itr1 = upper_bound(arr, 0, arr.Length - 1,
                               l / arr[i]);
  
        // Lower Bound for arr[j] such
        // that arr[j] >= l/arr[i]
        int itr2 = lower_bound(arr, 0, arr.Length - 1,
                               l / arr[i]);
        ans += itr1 - itr2;
    }
  
    // Print the answer
    Console.WriteLine(ans);
}
  
public static int lower_bound(int[] arr, int low,
                              int high, int X)
{
     
    // Base Case
    if (low > high)
    {
        return low;
    }
  
    // Find the middle index
    int mid = low + (high - low) / 2;
  
    // If arr[mid] is greater than
    // or equal to X then search
    // in left subarray
    if (arr[mid] >= X)
    {
        return lower_bound(arr, low, mid - 1, X);
    }
  
    // If arr[mid] is less than X
    // then search in right subarray
    return lower_bound(arr, mid + 1, high, X);
}
  
public static int upper_bound(int[] arr, int low,
                              int high, int X)
{
     
    // Base Case
    if (low > high)
        return low;
  
    // Find the middle index
    int mid = low + (high - low) / 2;
  
    // If arr[mid] is less than
    // or equal to X search in
    // right subarray
    if (arr[mid] <= X)
    {
        return upper_bound(arr, mid + 1, high, X);
    }
  
    // If arr[mid] is greater than X
    // then search in left subarray
    return upper_bound(arr, low, mid - 1, X);
}
 
// Driver code
public static void Main(string[] args)
{
     
    // Given Input
    int[] arr = { 4, 1, 2, 5 };
    int l = 4, r = 9;
    int n = arr.Length;
     
    // Function Call
    countPairs(arr, l, r, n);
}
}
 
// This code is contributed by sanjoy_62


Javascript


输出:
3

时间复杂度: O(NlogN)
辅助空间: O(1)