Count the Number of Fair Pairs

medium binary search sorting two pointers

Problem

Given a 0-indexed integer array nums and two integers lower and upper, count the number of fair pairs. A pair (i, j) is fair when 0 ≤ i < j < n and lower ≤ nums[i] + nums[j] ≤ upper.

Inputnums = [0,1,7,4,4,5], lower = 3, upper = 6
Output6
The fair pairs are (0,3), (0,4), (0,5), (1,3), (1,4), (1,5).
Inputnums = [1,7,9,2,5], lower = 11, upper = 11
Output1
Only the pair (2,3) sums to exactly 11.

def count_fair_pairs(nums, lower, upper):
    nums.sort()
    n = len(nums)
    total = 0
    for i in range(n):
        # values nums[j], j > i, with sum in [lower, upper]
        lo_t = lower - nums[i]
        hi_t = upper - nums[i]
        left = bisect_left(nums, lo_t, i + 1, n)
        right = bisect_right(nums, hi_t, i + 1, n)
        total += right - left
    return total
function countFairPairs(nums, lower, upper) {
  nums.sort((a, b) => a - b);
  const n = nums.length;
  let total = 0;
  for (let i = 0; i < n; i++) {
    // values nums[j], j > i, with sum in [lower, upper]
    const loT = lower - nums[i];
    const hiT = upper - nums[i];
    const left = lowerBound(nums, loT, i + 1, n);
    const right = upperBound(nums, hiT, i + 1, n);
    total += right - left;
  }
  return total;
}
long countFairPairs(int[] nums, int lower, int upper) {
    Arrays.sort(nums);
    int n = nums.length;
    long total = 0;
    for (int i = 0; i < n; i++) {
        // values nums[j], j > i, with sum in [lower, upper]
        long loT = lower - nums[i];
        long hiT = upper - nums[i];
        int left = lowerBound(nums, loT, i + 1, n);
        int right = upperBound(nums, hiT, i + 1, n);
        total += right - left;
    }
    return total;
}
long long countFairPairs(vector<int>& nums, int lower, int upper) {
    sort(nums.begin(), nums.end());
    int n = nums.size();
    long long total = 0;
    for (int i = 0; i < n; i++) {
        // values nums[j], j > i, with sum in [lower, upper]
        long long loT = lower - nums[i];
        long long hiT = upper - nums[i];
        auto left = lower_bound(nums.begin() + i + 1, nums.end(), loT);
        auto right = upper_bound(nums.begin() + i + 1, nums.end(), hiT);
        total += right - left;
    }
    return total;
}
Time: O(n log n) Space: O(1)