MediumArrayMathTwo PointersSortingUpdated Sep 2026

3649. Number of Perfect Pairs

Asked at Atlassian

Difficulty

Medium

Time

O(n log n)

Space

O(1) extra (ignoring the sort)

Pattern

Array

Companies

1

Problem

You get an integer array nums. A pair of indices (i, j) is called perfect when i < j and the two values a = nums[i], b = nums[j] satisfy two rules:

  • min(|a - b|, |a + b|) <= min(|a|, |b|)
  • max(|a - b|, |a + b|) >= max(|a|, |b|)

Here |x| means the absolute value of x (drop the minus sign). Count how many perfect pairs exist and return that count.

The two rules look scary, but they collapse into one simple test. If you sort the values so that a <= b, the pair is perfect exactly when b <= 2 * a. So the real job is: sort the array, then count pairs where the larger value is at most twice the smaller value. Note that pairs are counted by index, so equal values at different positions count as separate pairs.

Which pairs are perfect?

nums (sorted)01230123Values 1, 2, 3 are the candidates; 0 can never be thesmaller side.pair (1,2): 2 <= 2*1 ✓pair (2,3): 3 <= 2*2 ✓pair (0,1): 1 <= 2*0 ✗pair (1,3): 3 <= 2*1 ✗
After sorting, a pair is perfect when the larger value is at most twice the smaller value.

Constraints

  • ●2 <= nums.length <= 10^5
  • ●-10^9 <= nums[i] <= 10^9

Examples

Example 1
Inputnums = [0,1,2,3]
Output2
WhySorted: [0,1,2,3]. Pair (1,2): 2 <= 2*1, good. Pair (2,3): 3 <= 2*2, good. Pair (0,1): 1 <= 2*0 = 0 is false. Pair (1,3): 3 <= 2*1 = 2 is false. So only 2 pairs work.
Example 2
Inputnums = [-3,2,-1,4]
Output4
WhySorted: [-3,-1,2,4]. Check each left value: -3 allows up to -6, so no partner. -1 allows up to -2, so no partner. 2 allows up to 4, so both 2 and 4 qualify. 4 allows up to 8, but nothing is to its right. Total = 2 + 2 = 4.
Example 3
Inputnums = [1,10,100,1000]
Output0
WhyEach value is more than twice the one before it (10 > 2*1, 100 > 2*10, 1000 > 2*100), so no pair satisfies b <= 2*a. The answer is 0.

Asked At

1 companies
CompanyDifficulty
AtlassianMediumView all Atlassian questions →

How to Think About It

1

Brute force: check every pair (i, j) with i < j and test the condition — O(n²) time.

2

Rearrange the condition: for sorted array with a[i] <= a[j], the condition becomes a[j] - a[i] <= a[i], i.e., a[j] <= 2 * a[i].

3

Sort the array and for each element a[i], use binary search or two pointers to find the farthest a[j] such that a[j] <= 2 * a[i].

4

Two pointers: maintain a right pointer that advances as a[i] increases, since 2 * a[i] only grows.

5

Optimal: sort and use two pointers in O(n log n) time for sorting plus O(n) for the two-pointer scan.

Optimal Approach

Sort the array. For sorted a where a[i] <= a[j], the condition |a[i] - a[j]| <= min(a[i], a[j]) simplifies to a[j] <= 2 * a[i]. Use two pointers: for each left index i, advance the right pointer j as far as possible while a[j] <= 2 * a[i]. All pairs (i, i+1), (i, i+2), ..., (i, j) are valid. Add j - i to the result. This runs in O(n log n) for sorting and O(n) for the two-pointer scan.

Two pointers after sorting

nums (sorted)01230123ijStart with i = 0, j = 0. Limit is 2*0 = 0, so j cannotadvance past 0.nums (sorted)j - i - 1 = 2 pairs01230123iji = 1, limit 2. j advances to 3 (value 3 > 2), so add3 - 1 - 1 = 2 pairs.while j < n and nums[j] <= 2*nums[i]: j++answer += j - i - 1j never moves back, so the scan is O(n)
For each left index i, push right as far as possible while nums[right] <= 2*nums[i], then add right - i - 1 pairs.
ComplexityTime O(n log n)Space O(1) extra (ignoring the sort)Sorting dominates at O(n log n); the two-pointer scan afterwards is a single O(n) pass because the right pointer never moves backwards.

What Trips People Up in Real Interviews

1

Clarify whether the condition uses absolute value and whether negative numbers are possible.

2

Derive the simplified condition a[j] <= 2 * a[i] for sorted arrays — this is the key insight.

3

Make sure to count pairs where i < j only (avoid double counting).

4

Ask about integer overflow when computing 2 * a[i] — use long if needed.

5

Discuss why sorting preserves correctness: if the condition holds for sorted indices, it holds for the original pairs.

Solution Code

O(n log n) time
def countPerfectPairs(nums):
    nums.sort()
    n = len(nums)
    result = 0
    j = 0
    for i in range(n):
        while j < n and nums[j] <= 2 * nums[i]:
            j += 1
        result += j - i - 1
    return result

Pro at DSA?

Test your skills with a real FAANG-style mock interview.

Start a Mock Interview →

Frequently Asked Questions

What is the Number of Perfect Pairs problem?

Given an integer array nums, a pair (i, j) is called perfect if i < j and |nums[i] - nums[j]| <= min(nums[i], nums[j]). Return the total number of perfect pairs in the array.

How do you solve Number of Perfect Pairs?

The optimal approach runs in O(n log n) time and O(1) extra (ignoring the sort) space. Scroll up to "Optimal Approach" for the step-by-step walkthrough, diagrams, and code in Python, C++ and Java.

What companies ask Number of Perfect Pairs?

Number of Perfect Pairs is asked at Atlassian. It is a medium difficulty problem.

What are common mistakes on Number of Perfect Pairs?
  • Clarify whether the condition uses absolute value and whether negative numbers are possible.
  • Derive the simplified condition a[j] <= 2 * a[i] for sorted arrays — this is the key insight.
  • Make sure to count pairs where i < j only (avoid double counting).
  • Ask about integer overflow when computing 2 * a[i] — use long if needed.
  • Discuss why sorting preserves correctness: if the condition holds for sorted indices, it holds for the original pairs.