S2Q1 · Unique Sum Pairs¶
⚡ Quick Reference
Function: unique_sum_pairs(nums: list, k: int) -> set
Core idea: use a frequency counter -for each number, check if its complement exists (with enough occurrences for same-number pairs).
from collections import Counter
def unique_sum_pairs(nums: list, k: int) -> set:
count = Counter(nums)
result = set()
for num in count:
complement = k - num
if complement in count:
if num != complement or count[num] >= 2:
result.add(tuple(sorted((num, complement))))
return result
Key rules:
- Return sorted tuples so (1,3) and (3,1) are the same pair
- Same number can pair with itself only if it appears at least twice
- Use a set to automatically deduplicate pairs
Problem Statement¶
Problem
Write a function unique_sum_pairs(nums, k) that returns a set of unique sorted tuples where each tuple contains two elements from nums that sum to k. A number can pair with itself only if it appears at least twice.
Examples:
nums=[1, 2, 3, 2, 1], k=4
{(1, 3), (2, 2)}
nums=[1, 2, 3, 1], k=4
{(1, 3)}
nums=[3, 3, 3, 3], k=6
{(3, 3)}
nums=[1, 2, 3, 4, 5], k=10
set()
Understanding the problem¶
Two things to handle:
- Finding pairs: for each number
n, its complement isk - n. If both exist innums, they form a valid pair. - Same-number pairs:
(2, 2)is valid only if2appears at least twice.(1, 3)from[1, 2, 3, 1]requires just one1and one3-both present.
Why use Counter?
Counter(nums) gives the frequency of each number. This lets us:
- Check if a complement exists: complement in count
- Check if a same-number pair is valid: count[num] >= 2
Without Counter, we'd need two nested loops -O(n²). With Counter it's O(n).
Tracing the examples¶
[1, 2, 3, 2, 1], k=4:
count = {1:2, 2:2, 3:1}
num=1: complement=3, 3 in count, 1≠3 → add (1,3)
num=2: complement=2, 2 in count, 2==2 and count[2]=2≥2 → add (2,2)
num=3: complement=1, 1 in count, 3≠1 → (1,3) already in set
Result: {(1,3), (2,2)}
[1, 2, 3, 1], k=4:
count = {1:2, 2:1, 3:1}
num=1: complement=3, add (1,3)
num=2: complement=2, 2==2 but count[2]=1 < 2 → skip
num=3: complement=1, (1,3) already in set
Result: {(1,3)}
Solution approaches¶
def unique_sum_pairs(nums: list, k: int) -> set:
seen = set()
result = set()
for num in nums:
complement = k - num
if complement in seen:
pair = tuple(sorted((num, complement)))
result.add(pair)
seen.add(num)
# Handle same-number pairs: need at least 2 occurrences
# The above naturally handles this -when the 2nd occurrence
# of num is processed, the 1st is already in 'seen'
return result
Walk through the list, tracking seen numbers. When the complement is already seen, a valid pair is found. The second occurrence of a number pairs with the first -same-number pairs handled automatically.
from itertools import combinations
def unique_sum_pairs(nums: list, k: int) -> set:
return {tuple(sorted(pair))
for pair in combinations(nums, 2)
if pair[0] + pair[1] == k}
combinations(nums, 2) generates all 2-element pairs (without repetition from the same index). Any pair summing to k is included. Sorting and wrapping in a set deduplicates. Clean but O(n²).
from itertools import combinations
def unique_sum_pairs(nums: list, k: int) -> set:
return set(map(
lambda pair: tuple(sorted(pair)),
filter(lambda pair: sum(pair) == k, combinations(nums, 2))
))
filter(lambda pair: sum(pair) == k, ...) keeps only pairs summing to k. map(lambda pair: tuple(sorted(pair)), ...) normalises each pair. set(...) deduplicates.
Key takeaways¶
tuple(sorted(pair)) for canonical pairs
Sorting ensures (1,3) and (3,1) are the same tuple. Adding to a set then deduplicates automatically. Always normalise before adding to a set of pairs.
Counter for same-number pair validation
count[num] >= 2 checks whether a number can pair with itself. Without this guard, [1,2,3] with k=2 would incorrectly include (1,1).
combinations() vs Counter approach
combinations(nums, 2) is O(n²) but very readable. The Counter approach is O(n) and handles duplicates explicitly. For interview settings, know both and state the tradeoff.