↓Skip to main content
  1. LeetCode/

LeetCode 2563: Count the Number of Fair Pairs

·3 mins· ·
LeetCode Medium Two-Pointers Sorting Binary-Search Array
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2026-01-25

  • Submissions: WA → TLE → WA → TLE → AC

Approach
#

A pair (i, j) depends only on the sum of two values, not their order, so sort first.

Counting “sum in [lower, upper]” directly mixes an upper and a lower bound whose pointers want to move in opposite directions. Split it into two one-sided counts:

count(lower <= sum <= upper) = count(sum <= upper) - count(sum <= lower - 1)

count(sum <= limit) with converging pointers:

  • nums[left] + nums[right] > limit: right is too big; move it left.
  • Otherwise left pairs with every index in left + 1..right, so add right - left and move left right.

My Attempts
#

VersionProblem
Attempt 1, WAUsed one shared left/right across all i to find the partner range, without requiring j > i, so it paired elements with themselves and counted both orders. For [1, 1], lower = upper = 2, the answer is 1; this returned 4
Attempts 2 and 4, TLEReset the pointers to i + 1 and n - 1 for every i and walked inward: O(n^2)
Attempt 3, WAUsed left = max(i + 1, left) so left only moved right, but as nums[i] grows, the lower-bound position actually moves left, so left cannot be monotonic. For [-2, -1, -1, -1], lower = upper = -2, every pair of the three -1s sums to -2, so the answer is 3; this returned 2

Every one of these handled both bounds at once. Splitting into two one-sided counts passed.

Solution
#

class Solution:
    def countFairPairs(self, nums: List[int], lower: int, upper: int) -> int:
        nums.sort()

        def count_at_most(limit: int) -> int:     # pairs with sum <= limit
            left, right = 0, len(nums) - 1
            count = 0
            while left < right:
                if nums[left] + nums[right] > limit:
                    right -= 1
                else:
                    count += right - left
                    left += 1
            return count

        return count_at_most(upper) - count_at_most(lower - 1)

Alternatively, for each i, bisect the bounds in i + 1..n - 1, also O(n log n).

Complexity
#

Time O(n log n), space O(1) apart from sorting.

Mistakes to Avoid
#

  • Not requiring j > i: self-pairs and double counting.
  • Handling both bounds with one pair of pointers: the lower-bound position is not monotonic.
  • Resetting pointers for every i: O(n^2).

Interview Explanation
#

Pairs depend only on their sum, so I sort. I turn the range into “sum <= upper” minus “sum <= lower - 1”. Each one-sided count uses converging pointers: if the ends sum too high, move the right end left; otherwise the left end pairs with everything up to the right end, so add right - left and move the left end right. Both passes are O(n), so sorting dominates at O(n log n).

Related

LeetCode 1498: Number of Subsequences That Satisfy the Given Sum Condition
·2 mins
LeetCode Medium Two-Pointers Sorting Binary-Search Array
LeetCode 1498 note: only the minimum and maximum matter, so order does not and we can sort; fixing nums[left] as the minimum, the elements between are free, giving 2^(right - left) choices
LeetCode 825: Friends Of Appropriate Ages
·3 mins
LeetCode Medium Two-Pointers Sorting Binary-Search Array
LeetCode 825 note: after sorting, the people someone can invite have ages in (0.5 × age + 7, age], a contiguous range kept with two same-direction pointers, minus the person themself
LeetCode 1471: The k Strongest Values in an Array
·2 mins
LeetCode Medium Two-Pointers Sorting Array
LeetCode 1471 note: after sorting, the value farthest from the median is always at one of the ends, so converging pointers pick the stronger end k times
LeetCode 923: 3Sum With Multiplicity
·4 mins
LeetCode Medium Two-Pointers Sorting Hash-Table Counting Array
LeetCode 923 note: sort, fix the first number, and find the other two with converging pointers; equal end values are counted with a combination, different ones by multiplying each end’s duplicate count
LeetCode 948: Bag of Tokens
·2 mins
LeetCode Medium Two-Pointers Greedy Sorting Array
LeetCode 948 note: after sorting, buy score with the cheapest token and buy power with the most expensive one; trade for power only when score > 0, and stop when neither move works
LeetCode 3413: Maximum Coins From K Consecutive Bags
·3 mins
LeetCode Medium Sliding-Window Greedy Sorting Prefix-Sum Binary-Search Array
LeetCode 3413 note: the best k bags always have one end on a segment boundary; compute “left end at a segment start” and “right end at a segment end” (the latter by mirroring and reusing the same function)