Isomorphic Strings — Solution in Python, Java & C++
Isomorphic Strings solution explained: step-by-step approach, complexity and code in Python, Java, C++ and JavaScript. An easy problem.
Isomorphic Strings is an easy coding problem on strings and hash table, asked in Zomato, Sprinklr and Yelp interviews.
- Difficulty: Easy
- Topics: Strings, Hash Table
- Asked at: Zomato, Sprinklr, Yelp
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
Two strings are isomorphic if the characters in s can be replaced to get t, preserving order, with every occurrence of a character mapping to the same character and no two characters mapping to the same character.
Given s and t, return true if they are isomorphic.
Example 1
Input: s = "egg", t = "add"
Output: true
Example 2
Input: s = "foo", t = "bar"
Output: false
Example 3
Input: s = "paper", t = "title"
Output: true
Constraints
1 <= s.length <= 30t.length == s.lengthLowercase English letters.
Hints for Isomorphic Strings
Hint 1
Keep a mapping in BOTH directions — one map alone misses collisions.
Hint 2
Check consistency at every position before recording the pair.
How to solve Isomorphic Strings
Isomorphism is a bijection between characters, so one mapping table is not enough — you need both directions. s[i] -> t[i] must be consistent, and so must t[i] -> s[i]; without the second check, "ab" and "aa" would wrongly pass.
Approach
- Keep two tables: forward, from characters of
sto characters oft, and backward, the reverse. - For each position, look up both mappings.
- If either has been set before and disagrees with the current pair, return
false. - Otherwise record both directions and continue.
- Surviving the scan means the strings are isomorphic.
Why it works
A valid replacement scheme must be a function (each character of s maps to exactly one character of t) and injective (no two characters of s collapse onto the same character of t). The forward table enforces the first property and the backward table the second — together they make the mapping a bijection on the characters actually used, which is precisely the definition.
Complexity
- Time —
O(n) - Space —
O(1)
Pitfalls
- One map alone is the classic bug: it accepts
"ab"→"aa", which collapses two characters into one. - The strings are guaranteed to be the same length here, but a length check is the natural first guard in general.
- Use a sentinel that cannot be a real character (such as
0) to mean "unmapped". - A character legitimately maps to itself; that is not a special case.
Reference solution
Python
def isIsomorphic(s: str, t: str) -> bool:
if len(s) != len(t):
return False
m1 = {}
m2 = {}
for a, b in zip(s, t):
if a in m1 and m1[a] != b:
return False
if b in m2 and m2[b] != a:
return False
m1[a] = b
m2[b] = a
return TrueJava
public static boolean isIsomorphic(String s, String t) {
int[] forward = new int[128];
int[] backward = new int[128];
Arrays.fill(forward, -1);
Arrays.fill(backward, -1);
for (int i = 0; i < s.length(); i++) {
int a = s.charAt(i), b = t.charAt(i);
if (forward[a] == -1 && backward[b] == -1) {
forward[a] = b;
backward[b] = a;
} else if (forward[a] != b || backward[b] != a) {
return false;
}
}
return true;
}C++
bool isIsomorphic(string s, string t) {
vector<int> forward(128, -1), backward(128, -1);
for (int i = 0; i < (int) s.size(); i++) {
int a = (unsigned char) s[i], b = (unsigned char) t[i];
if (forward[a] == -1 && backward[b] == -1) {
forward[a] = b;
backward[b] = a;
} else if (forward[a] != b || backward[b] != a) {
return false;
}
}
return true;
}JavaScript
var isIsomorphic = function(s, t) {
if (s.length !== t.length) return false;
const m1 = new Map(), m2 = new Map();
for (let i = 0; i < s.length; i++) {
const a = s[i], b = t[i];
if (m1.has(a) && m1.get(a) !== b) return false;
if (m2.has(b) && m2.get(b) !== a) return false;
m1.set(a, b);
m2.set(b, a);
}
return true;
};Also on the editorial tab: C, C#, Go, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.
All 515 strings problems · the whole catalogue
Learn the technique: Strings · Hashing: Hash Maps and Hash Sets