Pairing numbers a,b in an array such a way that a2 b
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
The title has clearly lost an operator, so the first job is to pin down the intended inequality before choosing an algorithm. The non-trivial version of this problem is usually: form as many disjoint pairs as possible such that 2 * a <= b, because that leads to a real matching problem; if the rule were 2 * a >= b and pair order were flexible on non-negative numbers, the answer would collapse to floor(n / 2).
The useful interpretation: maximize pairs with 2 * a <= b
Assume we have an array of non-negative integers and want the maximum number of disjoint pairs where the smaller value in each pair is at most half of the larger value. After sorting, the task becomes: for each candidate small value, find a later unused large value that is at least twice as big.
The key observation is that using the smallest available valid large value is always safe. If a small number can pair with several larger values, spending the smallest valid one leaves more flexibility for the remaining elements.
That leads to a greedy two-pointer solution.
Why sorting and two pointers work
After sorting the array, split your thinking into two regions:
- the left side contains candidates for
a - the right side contains candidates for
b
Then advance through both sides:
- point
iat the first unused element in the left half - point
jat the first candidate in the right half - if
2 * arr[i] <= arr[j], record a pair and move both pointers - otherwise move
juntil you find a large enough partner
Because the array is sorted, once arr[j] is too small for arr[i], it is also too small for every later left-side value that is at least as large as arr[i]. So skipping that j for the current i is not wrong; it simply means j is not a useful large partner yet.
Python implementation
For the sample above, one valid output is [(1, 3), (3, 9), (4, 10)], giving three disjoint pairs.
The running time is dominated by sorting, so the algorithm is O(n log n). The pointer walk after sorting is linear.
Step-by-step example
Take the array [1, 2, 2, 3, 7, 8].
After sorting, it is already ordered. Start with i = 0 on 1 and j = 3 on 3.
- '
2 * 1 <= 3, so pair(1, 3)' - move to
2on the left and7on the right - '
2 * 2 <= 7, so pair(2, 7)' - move to the next
2on the left and8on the right - '
2 * 2 <= 8, so pair(2, 8)'
We get three pairs, which is optimal because all six elements are used.
This example shows why the right pointer starts in the second half. Any valid b must come from a later position than a, and starting too early only wastes comparisons.
What if the original condition was something else
This title might also have meant 2 * a >= b or even a^2 = b. Those are different problems.
If the rule is 2 * a >= b and you may swap elements inside each pair, then for non-negative numbers almost any two values can be made valid by naming the larger one as a. The problem stops being interesting.
If the rule is a^2 = b, the task becomes value matching, not greedy pairing by order. In that case you would count frequencies and look for squares. So before coding, confirm the intended operator.
Why this greedy strategy is correct
The algorithm never harms a future solution by pairing a small value with the smallest large value that works. Suppose a larger value was used instead. Then the smaller valid large value would still remain unused, but it could not help any earlier left element better than the one we are handling now. Using the smallest feasible partner preserves as many options as possible for later elements.
That is the same exchange argument used in many interval and matching greedies: if an optimal solution used a larger partner where a smaller valid one existed, we can swap them without reducing the number of pairs.
Common Pitfalls
A common mistake is solving the wrong inequality because the statement dropped an operator. Confirm the rule before implementing anything.
Another mistake is trying every possible pair with nested loops. That works for tiny arrays but is unnecessarily slow once sorting plus two pointers is available.
A third mistake is forgetting that pairs must be disjoint. Counting every valid comparison is not the same as building a maximum set of non-overlapping pairs.
Summary
- The meaningful array-pairing version is usually to maximize disjoint pairs with
2 * a <= b. - Sort the array and use two pointers, one in the left half and one in the right half.
- Pair each small value with the smallest valid large value.
- The algorithm runs in
O(n log n)time because sorting dominates. - If the original missing operator was different, the correct algorithm may change completely.
Related reading
- pandas - add new column to dataframe from dictionary
- Pandas convert dataframe to array of tuples
- Pandas DataFrame to List of Dictionaries
- Pandas DataFrame to List of Lists
- Parallel processing of database queue
- Parse a .py file, read the AST, modify it, then write back the modified source code
- Parse a URI String into Name-Value Collection
- Parse 'ul' and 'ol' tags

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.