File: occurrences-after-bigram/solution.py

Date: 2026-06-06

Time: 18:25

Purpose

This file is the solution and test suite for LeetCode 1078: Occurrences After Bigram. It finds all words in a text that immediately follow a given two-word sequence (bigram). In the project, it follows the standard pattern: one Solution class with the algorithm, one unittest.TestCase class with coverage, both in the same file.

Key Components

Solution.findOcurrences(text, first, second) -> List[str]

The single method on the class. Takes a space-separated string and two words forming a bigram, returns every word that appears directly after an occurrence of that bigram.

The core logic is a list comprehension over valid indices i in range(len(words) - 2). The - 2 bound ensures words[i + 2] never goes out of bounds. For each i, it checks whether words[i] and words[i + 1] match first and second, and if so, collects words[i + 2].

TestFindOcurrences

Seven test cases covering:

Patterns

Dependencies

Imports: typing.List (type annotation), unittest (test framework). No project-internal imports.

Imported by: The "Imported By" list in the prompt is misleading — those are unrelated test files across the repo that happen to share the same import unittest / from typing import List pattern. Nothing actually imports *this* module's Solution class.

Flow

1. text.split() tokenizes on whitespace into a list of words.

2. The list comprehension iterates i from 0 to len(words) - 3 (inclusive).

3. At each position, it checks whether the pair (words[i], words[i+1]) matches (first, second).

4. On match, words[i+2] is appended to the result.

5. Overlapping is handled naturally — if words[i+2] itself starts a new bigram match at position i+1, that's checked independently on the next iteration.

Time: O(n) where n is the number of words. Space: O(n) for split() and the result list.

Invariants

Error Handling

None. The method assumes valid input per the LeetCode contract: text is a non-empty string of lowercase words separated by single spaces, and first/second are non-empty lowercase words. If text is empty, split() returns [], the range is range(-2) which is empty, and the result is [] — it degrades gracefully without explicit handling.

Topics to Explore

Beliefs