File: number-of-good-pairs/solution.py

Date: 2026-06-06

Time: 18:19

Purpose

This file solves LeetCode 1512 — Number of Good Pairs. A "good pair" is defined as (i, j) where i < j and nums[i] == nums[j]. The file owns the algorithm implementation and exposes it via the standard Solution class that LeetCode and the project's test harness expect.

Key Components

Solution.numIdenticalPairs(nums: List[int]) -> int

The single method. It counts how many ordered pairs of equal elements exist in nums. Rather than brute-forcing all O(n^2) pairs, it uses a single-pass counting trick: for each element, the number of new good pairs it forms equals how many times that value has already been seen.

Patterns

Incremental combinatorics. When the k-th occurrence of some value arrives, it can pair with each of the (k-1) previous occurrences. So you accumulate seen[num] into count *before* incrementing seen[num]. This avoids computing C(n, 2) after the fact and keeps everything in one pass.

defaultdict(int) as a frequency map. The zero-default lets the code skip existence checks — seen[num] is always valid, starting at 0.

Standard LeetCode class shape. A Solution class with a single public method matching the problem signature. Every solution in this repo follows this convention, which is why hundreds of test files can import it uniformly.

Dependencies

Imports: collections.defaultdict (frequency tracking) and typing.List (type annotation). No project-internal dependencies.

Imported by: The companion number-of-good-pairs/test_solution.py. The massive "Imported By" list in the prompt is an artifact of the test harness structure — those other test files import their *own* solution.py, not this one.

Flow

1. Initialize count = 0 and an empty frequency map seen.

2. Iterate through nums once, left to right.

3. For each num: add seen[num] (number of prior occurrences) to count, then increment seen[num].

4. Return count.

For input [1, 2, 3, 1, 1, 3]:

Result: 4.

Invariants

Error Handling

None. The method assumes valid input per LeetCode constraints (1 <= nums.length <= 100, 1 <= nums[i] <= 100). Empty lists would return 0 correctly since the loop body never executes.

Topics to Explore

Beliefs