File: isomorphic-strings/solution.py

Date: 2026-06-06

Time: 17:09

Purpose

This file implements LeetCode 205 — Isomorphic Strings. It determines whether two strings s and t have a one-to-one character mapping — every occurrence of character x in s maps to the same character y in t, and no two distinct characters in s map to the same character in t.

The file exports a single function isisomorphic consumed by testsolution.py in the same directory (and, per the import list, by hundreds of other test files — likely via a shared test harness that discovers solutions generically).

Key Components

is_isomorphic(s, t) -> bool — The sole public function. Contract:

Two internal dictionaries enforce the bijection:

Patterns

Dual-map bijection enforcement. This is the standard idiom for checking isomorphism between two sequences. A single map only enforces a function (many-to-one is allowed); the second map enforces injectivity, making it a bijection. This pattern appears wherever you need to verify a one-to-one correspondence — e.g., word pattern matching (LeetCode 290).

Early-return on violation. The function short-circuits with return False the moment it detects a conflict, avoiding unnecessary iteration over the rest of the strings.

Dependencies

Flow

For each position i, zip(s, t) yields the character pair (cs, ct):

1. Forward conflict check (line 17–19): If cs was previously mapped, verify it still maps to ct. If not → False.

2. Reverse conflict check (line 20–21): If cs is unmapped but ct is already claimed by a different s-character → False. This prevents two distinct s-characters from collapsing onto the same t-character.

3. Register new mapping (line 22–24): Both directions recorded simultaneously.

4. Success (line 26): If the entire string is consumed without conflict, return True.

Example trace with s="egg", t="add":

Example trace with s="foo", t="bar":

Invariants

1. Bijection maintained at every step: After processing position i, for every key k in stot, ttos[stot[k]] == k and vice versa. The two maps are always consistent mirrors.

2. Equal-length assumption: zip silently truncates to the shorter string. The function relies on the LeetCode guarantee that len(s) == len(t) — it does not validate this.

3. Both maps updated atomically: A new pair is always written to both stot and ttos together (lines 23–24), never one without the other.

Error Handling

None. The function assumes valid input per the problem constraints. No exceptions are raised or caught. Invalid input (e.g., strings of different lengths) would silently produce an incorrect result rather than an error.