S2Q1 · Zero Sum Pairs¶
⚡ Quick Reference
Function: find_zero_pairs(nums: list) -> set
Core idea: For each pair of elements (including repeated values), check if their sum is 0. Store as sorted tuples in a set to guarantee uniqueness.
def find_zero_pairs(nums):
result = set()
for i in range(len(nums)):
for j in range(i + 1, len(nums)):
if nums[i] + nums[j] == 0:
result.add(tuple(sorted([nums[i], nums[j]])))
return result
Key rules:
- Each pair is a sorted tuple (a, b) where a <= b
- Use a set to automatically deduplicate
- 0 can pair with 0 only if it appears at least twice
- Start j from i + 1 to avoid using the same element twice
Problem Statement¶
Problem
Write a function find_zero_pairs(nums) that takes a list of integers and returns a set of unique sorted tuples, where each tuple is a pair of numbers whose sum is 0.
- Each pair must be sorted in ascending order
- The result contains unique pairs only
0can pair with itself only if it appears at least twice
Examples:
find_zero_pairs([1, -1, 2, -2, 3])
{(-2, 2), (-1, 1)}
find_zero_pairs([0, 0, 0])
{(0, 0)}
find_zero_pairs([1, 2, 3])
set()
Understanding the problem¶
Two properties guarantee correctness:
-
Sorted tuple --
tuple(sorted([a, b]))ensures(-2, 2)and(2, -2)both become(-2, 2), so the same pair found at different index positions produces the same tuple. -
Set of tuples -- adding to a
setautomatically discards duplicates. Even if[1, -1, 1, -1]produces four qualifying pairs across all index combinations, the set only keeps one(-1, 1).
Why start j at i+1?
Using j starting from i + 1 (not 0) means we only consider each unordered pair once: (i, j) but never (j, i). Without this, the same pair appears twice and -- more importantly -- nums[i] + nums[i] would let a single element pair with itself.
Tracing [0, 0, 0]:
| i | j | nums[i] |
nums[j] |
Sum | Sorted tuple |
|---|---|---|---|---|---|
| 0 | 1 | 0 | 0 | 0 | (0, 0) ✅ |
| 0 | 2 | 0 | 0 | 0 | (0, 0) -- duplicate, set ignores |
| 1 | 2 | 0 | 0 | 0 | (0, 0) -- duplicate, set ignores |
Final result: {(0, 0)}
Solution approaches¶
def find_zero_pairs(nums: list) -> set:
result = set()
for i in range(len(nums)):
for j in range(i + 1, len(nums)): # j > i avoids reusing same element
if nums[i] + nums[j] == 0:
pair = tuple(sorted([nums[i], nums[j]])) # sort so (-2,2) not (2,-2)
result.add(pair) # set handles deduplication
return result
Key takeaways¶
Set of tuples for unique pairs
A set only stores distinct elements. Since tuples are hashable, result.add(tuple(...)) gives free deduplication -- no need to check if the pair already exists.
tuple(sorted([a, b])) for canonical order
Sorting before wrapping in a tuple means the same pair found in any order always produces the same key. (-1, 1) and (1, -1) become the same (-1, 1) after sorting.
itertools.combinations for pair generation
combinations(nums, 2) yields all unique index pairs (i, j) with i < j -- exactly what the nested for loop does, but in one line. It also handles the "no self-pairing" rule automatically.