从给定数组中计数其乘积在给定范围内的对
给定一个大小为N的数组arr[]以及整数L和R ,任务是计算对[arr i , arr j ]的数量,使得i < j和arr[i] * arr[j]的乘积 位于给定范围[L, R]内,即L ≤ arr[i] * arr[j] ≤ R。
例子:
Input: arr[ ] = {4, 1, 2, 5}, L = 4, R = 9
Output: 3
Explanation: Valid pairs are {4, 1}, {1, 5} and {4, 2}.
Input: arr[ ] = {1, 2, 5, 10, 5}, L = 2, R = 15
Output: 6
Explanation: Valid pairs are {1, 2}, {1, 5}, {1, 10}, {1, 5}, {2, 5}, {2, 5}.
朴素方法:解决问题的最简单方法是从数组中生成所有可能的对,并为每一对检查其乘积是否在[L, R]范围内。
时间复杂度: O(N 2 )
辅助空间: O(1)
有效的方法:这个问题可以通过排序和二分搜索技术来解决。请按照以下步骤解决此问题:
- 对数组arr[] 进行排序。
- 初始化一个变量,比如ans为0,以存储乘积在[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)