AlgoMaster Logo

Number of Pairs Satisfying Inequality

hardFrequencyUpdated September 21, 2026

Understanding the Problem

The inequality nums1[i] - nums1[j] <= nums2[i] - nums2[j] + diff has four array accesses and a constant, but it simplifies once we group the terms by index.

Rearranging the inequality:

nums1[i] - nums1[j] <= nums2[i] - nums2[j] + diff

nums1[i] - nums2[i] <= nums1[j] - nums2[j] + diff

If we define a new array arr where arr[k] = nums1[k] - nums2[k], the inequality becomes:

arr[i] <= arr[j] + diff

Or equivalently: arr[i] - arr[j] <= diff

So the problem reduces to: given an array arr, count all pairs (i, j) with i < j such that arr[i] - arr[j] <= diff. This is a variant of counting inversions. The i < j index constraint combined with a value comparison is what merge sort-based counting and order-statistic structures like a Binary Indexed Tree are built to handle efficiently.

Key Constraints:

  • 2 <= n <= 10^5. With n up to 100,000, an O(n^2) brute force performs about 5 billion comparisons, too slow for typical limits. We need O(n log n) or better.
  • -10^4 <= nums1[i], nums2[i] <= 10^4. The difference arr[k] = nums1[k] - nums2[k] ranges from -20,000 to 20,000. This bounded range lets a BIT index directly into a fixed-size array without coordinate compression.
  • The answer can reach n*(n-1)/2, roughly 5 billion when n = 100,000. That overflows a 32-bit signed integer, so the count must use a 64-bit type.

Approach 1: Brute Force

Intuition

Build the array arr where arr[k] = nums1[k] - nums2[k], then check every pair (i, j) with i < j against the simplified condition arr[i] - arr[j] <= diff. Two nested loops cover all pairs. This is the baseline before optimizing.

Algorithm

  1. Build the array arr where arr[k] = nums1[k] - nums2[k] for each index k.
  2. Initialize a counter count = 0.
  3. For each i from 0 to n - 2, for each j from i + 1 to n - 1, check if arr[i] - arr[j] <= diff.
  4. If the condition holds, increment count.
  5. Return count.

Example Walkthrough

Input: nums1 = [3, 2, 5], nums2 = [2, 2, 1], diff = 1

First, build arr = [1, 0, 4].

  • Pair (0, 1): arr[0] - arr[1] = 1 - 0 = 1 <= 1. Valid.
  • Pair (0, 2): arr[0] - arr[2] = 1 - 4 = -3 <= 1. Valid.
  • Pair (1, 2): arr[1] - arr[2] = 0 - 4 = -4 <= 1. Valid.

Result: 3 pairs.

Code

The quadratic scan is wasteful: for a fixed j, it recompares against every earlier element one at a time. Sorting the values lets us count matching elements in bulk, and merge sort can do this sorting while still respecting the i < j ordering.

Approach 2: Merge Sort

Intuition

Merge sort splits the array into a left half (smaller indices) and a right half (larger indices), sorts each, then merges them. The counting happens just before each merge. At that point every element in the left half had a smaller original index than every element in the right half, so the cross-boundary pairs are precisely the i < j pairs where i is in the left half and j is in the right half. Pairs that lie entirely inside one half are counted by the recursive calls on that half.

Both halves are sorted just before the merge. So for each element arr[j] in the right half, we count how many elements arr[i] in the left half satisfy arr[i] <= arr[j] + diff. Because the left half is sorted ascending, those matching elements form a prefix, and a single forward-moving pointer finds the prefix length.

The right half is also sorted ascending, so as j advances, arr[j] and the threshold arr[j] + diff only increase. The pointer therefore never moves backward: it advances across all of the right half once per merge, making the counting step O(n) per merge level and O(n log n) overall.

Algorithm

  1. Build the array arr where arr[k] = nums1[k] - nums2[k].
  2. Run a modified merge sort on arr.
  3. In each merge step, before the standard merge, count valid pairs:
    • Use a pointer p starting at the beginning of the left half.
    • For each element arr[j] in the right half, advance p while arr[p] <= arr[j] + diff.
    • The number of valid left-half elements for this j is p - left_start.
    • Add this count to the total.
  4. After counting, perform the standard merge to sort the subarray.
  5. Return the total count.

Example Walkthrough

1Build arr: arr[k] = nums1[k] - nums2[k] -> [1, 0, 4], diff = 1
0
1
3-2=1
1
0
2-2=0
2
4
5-1=4
1/7

Code

Merge sort reaches O(n log n) but needs a custom recursive merge. The next approach reaches the same bound with a single left-to-right pass, delegating the counting to a Binary Indexed Tree.

Approach 3: Binary Indexed Tree (BIT)

Intuition

Instead of using merge sort's divide-and-conquer structure to enforce the i < j ordering, process elements from left to right. By the time we reach index j, all elements at indices 0 through j - 1 have already been processed, so we need an efficient way to count how many of those earlier values satisfy arr[i] <= arr[j] + diff.

A Binary Indexed Tree (also called a Fenwick Tree) supports two operations in O(log n) time: update a position (add 1 to record that a value has been seen) and query a prefix sum (count how many recorded values fall at or below a threshold). Counting earlier values at or below arr[j] + diff is a prefix-sum query.

The values of arr[k] range from -20,000 to 20,000, so adding a fixed offset of 20,001 maps them to positive indices. For each index j, query the BIT for the count of recorded values at most arr[j] + diff, add that to the result, then record arr[j]. Querying before recording enforces i < j: only values from earlier indices are in the tree when index j is counted.

Algorithm

  1. Build the array arr where arr[k] = nums1[k] - nums2[k].
  2. Initialize a BIT of size large enough to cover all possible values (offset by a constant to handle negatives).
  3. For each index j from 0 to n - 1:
    • Compute the threshold arr[j] + diff.
    • Query the BIT for the count of values at most the threshold. Add this to the result.
    • Insert arr[j] into the BIT by updating its position.
  4. Return the total count.

Example Walkthrough

1Build arr: arr[k] = nums1[k] - nums2[k] -> [1, 0, 4], diff = 1
0
1
3-2=1
1
0
2-2=0
2
4
5-1=4
1/5

Code