计算给定数组中的对,其总和位于给定范围内
给定一个由N个整数和两个整数L和R组成的数组arr[] ,任务是计算总和在[L, R]范围内的对数。
例子:
Input: arr[] = {5, 1, 2}, L = 4, R = 7
Output: 2
Explanation:
The pairs satisfying the necessary conditions are as follows:
- (5, 1): Sum = 5 + 1 = 6, which lies in the range [4, 7].
- (5, 2): Sum = 5 + 2 = 7, which lies in the range [4, 7].
Therefore, the count of such pairs is 2.
Input: arr[] = {5, 1, 2, 4, 3}, L = 5, R = 8
Output: 7
朴素方法:解决给定问题的最简单方法是生成所有可能的对并计算总和在[L, R]范围内的那些对。检查所有对后,打印对的总数。
时间复杂度: O(N 2 )
辅助空间: O(1)
有效方法:上述方法还可以通过对数组进行排序然后执行二分搜索来找到每个数组元素arr[i]的元素数,这样总和不会超过给定范围来优化。请按照以下步骤解决问题:
- 按升序对数组arr[]进行排序。
- 将变量初始化为N – 1并计数为0以存储总和位于[L, R]范围内的对数。
- 迭代直到right大于0并执行以下步骤:
- 找到与arr[right]之和大于或等于L的元素的起始索引,并将其存储在变量中,例如start 。
- 找到arr[right]之前与arr[right]之和小于或等于R的元素的结束索引,然后将其存储在变量中,例如end 。
- 如果end大于等于start ,则将(end – start + 1)添加到表示与当前元素的和位于[L, R]范围内的元素数量的计数中,然后向右减1 。
- 完成上述步骤后,打印count的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to count pairs whose
// sum lies over the range [L, R]
int countPairSum(int arr[], int L,
int R, int N)
{
// Sort the given array
sort(arr, arr + N);
int right = N - 1, count = 0;
// Iterate until right > 0
while (right > 0) {
// Starting index of element
// whose sum with arr[right] >= L
auto it1
= lower_bound(arr, arr + N,
L - arr[right]);
int start = it1 - arr;
// Ending index of element
// whose sum with arr[right] <= R
auto it2
= upper_bound(arr, arr + N,
R - arr[right]);
--it2;
int end = it2 - arr;
// Update the value of end
end = min(end, right - 1);
// Add the count of elements
// to the variable count
if (end - start >= 0) {
count += (end - start + 1);
}
right--;
}
// Return the value of count
return count;
}
// Driver Code
int main()
{
int arr[] = { 5, 1, 2, 4, 3 };
int L = 5, R = 8;
int N = sizeof(arr) / sizeof(arr[0]);
cout << countPairSum(arr, L, R, N);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
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;
}
// Function to count pairs whose
// sum lies over the range [L, R]
static int countPairSum(int arr[], int L,
int R, int N)
{
// Sort the given array
Arrays.sort(arr);
int right = N - 1, count = 0;
// Iterate until right > 0
while (right > 0) {
// Starting index of element
// whose sum with arr[right] >= L
int it1
= lowerBound(arr, 0,N,
L - arr[right]);
it1++;
int start = it1 - arr[0];
// Ending index of element
// whose sum with arr[right] <= R
int it2
= upperBound(arr, 0,N,
R - arr[right]);
int end = it2 - arr[0];
// Update the value of end
end = Math.min(end, right - 1);
// Add the count of elements
// to the variable count
if (end - start >= 0) {
count += (end - start +1);
}
right--;
}
// Return the value of count
return count;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 5, 1, 2, 4, 3 };
int L = 5, R = 8;
int N = arr.length;
System.out.print(countPairSum(arr, L, R, N));
}
}
// This code is contributed by gauravrajput1
Python3
# Python3 program for the above approach
from bisect import bisect_left, bisect_right
# Function to count pairs whose
# sum lies over the range [L, R]
def countPairSum(arr, L, R, N):
# Sort the given array
arr.sort()
right = N - 1
count = 0
# Iterate until right > 0
while (right > 0):
# Starting index of element
# whose sum with arr[right] >= L
it1 = bisect_left(arr, L - arr[right])
start = it1
# Ending index of element
# whose sum with arr[right] <= R
it2 = bisect_right(arr, R - arr[right])
it2 -= 1
end = it2
# Update the value of end
end = min(end, right - 1)
# Add the count of elements
# to the variable count
if (end - start >= 0):
count += (end - start + 1)
right -= 1
# Return the value of count
return count
# Driver Code
if __name__ == '__main__':
arr = [ 5, 1, 2, 4, 3 ]
L = 5
R = 8
N = len(arr)
print(countPairSum(arr, L, R, N))
# This code is contributed by SURENDRA_GANGWAR
C#
// C# program for the above approach
using System;
public class GFG {
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;
}
// Function to count pairs whose
// sum lies over the range [L, R]
static int countPairSum(int []arr, int L, int R, int N)
{
// Sort the given array
Array.Sort(arr);
int right = N - 1, count = 0;
// Iterate until right > 0
while (right > 0) {
// Starting index of element
// whose sum with arr[right] >= L
int it1 = lowerBound(arr, 0, N, L - arr[right]);
it1++;
int start = it1 - arr[0];
// Ending index of element
// whose sum with arr[right] <= R
int it2 = upperBound(arr, 0, N, R - arr[right]);
int end = it2 - arr[0];
// Update the value of end
end = Math.Min(end, right - 1);
// Add the count of elements
// to the variable count
if (end - start >= 0) {
count += (end - start + 1);
}
right--;
}
// Return the value of count
return count;
}
// Driver Code
public static void Main(String[] args) {
int []arr = { 5, 1, 2, 4, 3 };
int L = 5, R = 8;
int N = arr.Length;
Console.Write(countPairSum(arr, L, R, N));
}
}
// This code is contributed by gauravrajput1
Javascript
输出:
7
时间复杂度: O(N*log N)
辅助空间: O(1)