📌  相关文章
📜  计算给定数组中的对,其总和位于给定范围内

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

计算给定数组中的对,其总和位于给定范围内

给定一个由N个整数和两个整数LR组成的数组arr[] ,任务是计算总和在[L, R]范围内的对数。

例子:

朴素方法:解决给定问题的最简单方法是生成所有可能的对并计算总和在[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)