Skip to content

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
  • 0 can pair with itself only if it appears at least twice

Examples:

Call
find_zero_pairs([1, -1, 2, -2, 3])
Output
{(-2, 2), (-1, 1)}
Call
find_zero_pairs([0, 0, 0])
Output
{(0, 0)}
Call
find_zero_pairs([1, 2, 3])
Output
set()

Understanding the problem

Two properties guarantee correctness:

  1. 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.

  2. Set of tuples -- adding to a set automatically 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
from collections import Counter

def find_zero_pairs(nums: list) -> set:
    count = Counter(nums)
    result = set()
    for n in count:
        if n == 0 and count[n] >= 2:
            result.add((0, 0))
        elif n < 0 and -n in count:          # process only n < 0 to avoid duplicates
            result.add((n, -n))
    return result
from itertools import combinations

find_zero_pairs = lambda nums: {
    tuple(sorted(p)) for p in combinations(nums, 2) if sum(p) == 0
}

Key takeaways

01

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.

02

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.

03

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.