# LeetCode – Isomorphic Strings (Java)

Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the characters in s can be replaced to get t.

For example,"egg" and "add" are isomorphic, "foo" and "bar" are not.

Java Solution 1

We can define a map which tracks the char-char mappings. If a value is already mapped, it can not be mapped again.

```public boolean isIsomorphic(String s, String t) { if(s.length()!=t.length()){ return false; }   HashMap<Character, Character> map1 = new HashMap<>(); HashMap<Character, Character> map2 = new HashMap<>();   for(int i=0; i<s.length(); i++){ char c1 = s.charAt(i); char c2 = t.charAt(i);   if(map1.containsKey(c1)){ if(c2!=map1.get(c1)){ return false; } }else{ if(map2.containsKey(c2)){ return false; }   map1.put(c1, c2); map2.put(c2, c1); } }   return true; }```

Time complexity is O(n) and space complexity is O(n), where n is the length of the input string.

Java Solution 2

We can also simply check if a value is mapped twice by checking the number of unique elements.

```public boolean isIsomorphic(String s, String t) { if (s.length() != t.length()) { return false; }   HashMap<Character, Character> map = new HashMap<>(); for (int i = 0; i < s.length(); i++) { char c1 = s.charAt(i); char c2 = t.charAt(i);   if (map.containsKey(c1)) { if (map.get(c1) != c2) { return false; } } else { map.put(c1, c2); } }   HashSet<Character> set = new HashSet<>(map.values()); if (set.size() == map.values().size()) { return true; }   return false; }```
Category >> Algorithms >> Interview >> Java
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
```<pre><code>
String foo = "bar";
</code></pre>
```
• Ujvári Bálint

wouldnt this return true for strings that are the same length and have the same set of characters in them?
thats not the same as isomorphic, because the order of the characters is also a factor

• Ujvári Bálint

not sure what you mean by “seems its not quote accept”

but abaab and cddcd are not isomorphic, so Bukary’s solution should not accept them as isomorphic

• // This has less space complexity

private static boolean isIsomorphic(String s, String t) throws IllegalAccessException {
if (s == null || t == null) {
throw new IllegalAccessException(“null values”);
}

if (s.length() != t.length()) {
return false;
}

for (int i = 1; i < s.length(); ++i) {
boolean sChange = s.charAt(i) == s.charAt(i – 1);
boolean tChange = t.charAt(i) == t.charAt(i – 1);

if (sChange != tChange) {
return false;
}
}

return true;

}

• Rakesh Venkatesh

your solution doesnt work for “egg” and “bab”. Your solution returns true but they are not isomorphic

• cheng fang

seems its not quite accept if we use this solution

` isIsomorphic("abaab", "cddcd")`

How about following solution in Python?:
After checking for null and unequal length:

l1 = list(word1)
l2 = list(word2)
pp = {}
for i, j in enumerate(l1):
if j not in pp:
pp[j] = list(l2[i])
else:
newls = pp[j]
newls.append(l2[i])
pp[j] = newls

for key, things in pp.items():
var = len(set(things))
if var == 1:
continue
else:
print(‘words: ‘{}’and ‘{}’ are not isomorphic’.format(word1, word2))
break
if var == 1:
print(‘words: ‘{}’and ‘{}’ are isomorphic’.format(word1, word2))

How about following solution in Python:

l1 = list(word1)
l2 = list(word2)
pp = {}
for i, j in enumerate(l1):
if j not in pp:
pp[j] = list(l2[i])
else:
newls = pp[j]
newls.append(l2[i])
pp[j] = newls

for key, things in pp.items():
var = len(set(things))
if var == 1:
continue
else:
print(‘words: ‘{}’and ‘{}’ are not isomorphic’.format(word1, word2))
break
if var == 1:
print(‘words: ‘{}’and ‘{}’ are isomorphic’.format(word1, word2))

• Aafreen Sheikh

The containsValue check can be avoided if we use the map as a bidirectional map. So when we find that ‘e’ maps to ‘a’, we first check that map.contains(‘a’) and map.contains(‘e’) both should be false. If so, we do: map.put(‘e’,’a’) and map.put(‘a’,’e’). This way we can look up both ways and implement this code in O(1).

• Bukary Kandeh

Yet Another Solution 🙂 See my code in the link or below code:
https://ide.geeksforgeeks.org/zuwGLQKlWV
``` private static boolean isIsomorphic(String s, String t) { if(s == null || t == null) return false; if(s.length() != t.length()) return false;```

``` Map sMp = new HashMap(); for(char ch : s.toCharArray()){ if(sMp.containsKey(ch)){ sMp.put(ch, sMp.get(ch) + 1); } else sMp.put(ch, 1); } Map tMp = new HashMap(); for(char ch : t.toCharArray()){ if(tMp.containsKey(ch)){ tMp.put(ch, tMp.get(ch) + 1); } else tMp.put(ch, 1); } if(sMp.size() != tMp.size()) return false; List lstOne = new ArrayList(); for(Integer entryOne : sMp.values()){ lstOne.add(entryOne.intValue()); } List lstTwo = new ArrayList(); for(Integer entryTwo : tMp.values()){ lstTwo.add(entryTwo.intValue()); } ```

``` Collections.sort(lstOne); Collections.sort(lstTwo); for (int i=0; i<lstOne.size(); i++){ if(lstOne.get(i) != lstTwo.get(i)){ return false; } } return true; } ```

• LR

aab and xzz are not isomorphic as a->x and a->z

• Arezou Moussavi

Given handling the empty cases and wrong types (from other solutions) this works in python:
if len(set(str1)) != len(set(str2)):
print (‘False’)
else:
print(‘True’)

• Partha Pratim Sanyal

map.containsValue() is a O(n) operation, so the solution presented above is O(n^n)

• jlogan

Does any of these solution work for
“aab”, “xzz”

a->z
b->x makes this isomorphic,

but every one of the solutions i have seen (geeks,leet,sovflow, this one) do not address this. Highly likely i got my isomorphism wrong.

• dan

bool checkMap(string s1, string s2)
{
Dictionary m = new Dictionary();
for (int i = 0; i < s1.Length; i++)
{
if (m.ContainsKey(s1.Substring(i, 1)) || m.ContainsValue(s2.Substring(i, 1))) continue;
}
foreach(KeyValuePair item in m){
s2=s2.Replace(item.Value, item.Key);
}
if (s1 == s2)
return true;
else return false;
}

• jitendra

if len(s)==len(t):
for in range(len(s)):
s=s.replace(s[i],t[i])
if s==t:
print(‘they are isomorphic’)

Hi,
The solution above has O(N2) time complexity as map.containsValue(c2) will run in O(N) not O(1_

• Greg Mueller

Here’s what I came up with:

``` def is_isomorphic(source, target): if type(source) != type('') or type(target) != type(''): raise ValueError('Source and Target must be of type string.') char_map = {} for s, t in zip(source, target): if t != char_map.setdefault(s, t): return False return True if len(source) == len(target) else False ```

• Udaydeep Thota

You code doesn’t work for “ab” and “aa”

• Samir

Hi,
Below code runs fine for given input s=”ab”,t=”aa” ; on eclipse but not on leetcode’s compliter.
However this code was able to pass 26/30 test case and takes 3ms of execution time.

``` public boolean isIsomorphic(String s, String t) { if(s.equals("") || t.equals("")){ return true; }```

``` String sArray[] = s.split(""); String tArray[] = t.split(""); Map sMap= new HashMap(); Map tMap= new HashMap(); Set sSet = new HashSet(); Set tSet = new HashSet(); ```

``` for(int i=1;i<sArray.length;i++){ sMap.put(i, sArray[i]); } for(int i=1;i<sArray.length;i++){ tMap.put(i, tArray[i]); } for(Integer key1 : sMap.keySet()){ sSet.add(sMap.get(key1)); } for(Integer key2 : tMap.keySet()){ tSet.add(tMap.get(key2)); } System.out.println(sSet+" "+tSet); if(sSet.size() == tSet.size() ){ return true; }else{ return false; } } ```

• Samir

For input String str1=”aba”, str2=”baa”; this code will not work

• Samir

Very easy solution

``` public boolean isIsomorphic(String s, String t) { if(s==null||t==null) return false;```

``` String sArray[] = s.split(""); String tArray[] = t.split(""); Set sSet= new HashSet(Arrays.asList(sArray)); Set tSet= new HashSet(Arrays.asList(tArray)); System.out.println(sSet.size()+" "+tSet.size()); if(sSet.size() == tSet.size()){ return true; } else{ return false; } } ```

• Nakeer

should be (s1 != null && s2 != null && s1.length() == s2.length() ) {
}
return false;

• Nakeer

Actually if you use && it will be much more faster

if (s1.length() == s2.length() && s1 != null && s2 != null) {
}
return false;

• Guy Kahlon

How does this solution is O (n) time? The operation containsValue itself is O(n) time, so, in the worst case this solution can take O(n^2) time.

• Mahesh V Shet (CP QA-BLR)

Here is my Solution:

• Matias SM

I believe that you only need a (hash)set to check if a mapping already exists. If it does, then the creation of a new one would make the strings not isomorphic.

You would use the first map to check if the current char (source str) has already a mapping, and the set to check if a new mapping can be created (to the char in the dst str).

• Roger Camargo

A python solution:

``` def is_isomorphic(first, second): if not first or not second: return False if len(first) != len(second): return False word_map = {} final_word = "" for position in range(len(first)): word_map.update({first[position]: second[position]})```

``` for char in first: final_word += word_map[char] return final_word == second ```

```def test_isomorphic(): assert is_isomorphic("egg", "add") == True assert is_isomorphic("foo", "bar") == False assert is_isomorphic("abca", "zbxz") == True assert is_isomorphic("ab", "zbxz") == False assert is_isomorphic("", "zbxz") == False assert is_isomorphic(None, "zbxz") == False ```

• Luis Zafra

I think this work fine:

``` import java.util.HashMap; import java.util.Map;```

``` public class Isomorphic { public static void main(String[] args) { String a = "add"; String b = "egg"; System.out.println(isIsomorphic(a, b)); } private static boolean isIsomorphic(String s, String t) { if (s == null || t == null || (s.length() != t.length())) { return false; } if (s.length() == 0 && t.length() == 0) { return true; } Map map = new HashMap(); for (int i = 0; i < s.length(); i++) { Character c1 = s.charAt(i); Character c2 = t.charAt(i); if (!map.containsKey(c1)) { if (!map.containsValue(c2)) { map.put(c1, c2); } else { return false; } } else if (!map.get(c1).equals(c2)) { return false; } } return true; } } ```

• Michael Voong

Swift:

``` func isIsomorphic(s1: String, s2: String) -> Bool { if s1.characters.count == 0 { return false } if s1.characters.count != s2.characters.count { return false } let s1Array = s1.characters.map { String(\$0) } let s2Array = s2.characters.map { String(\$0) } var map = [String: String]() for (i, s1Value) in s1Array.enumerate() { if let existingValue = map[s1Value] where existingValue != s2Array[i] { return false } map[s1Value] = s2Array[i] } return true } ```

• Ankit Shah

``` import java.util.*; public class IsomorphicString { public static boolean isomorphic(String s, String t) { if(s == null) { return false; } if(t == null) { return false; } if(s.length() != t.length()) { return false; } ```

``` if(s.length() == 0 && t.length() == 0) return true; Map map = new HashMap(); for(int i = 0; i < s.length(); i++) { if(map.containsKey(s.charAt(i))) { if(map.get(s.charAt(i)) != t.charAt(i)) { return false; } } else { map.put(s.charAt(i), t.charAt(i)); } } return true; } public static void main(String[] args) { String s = "egg"; String t = "ftd"; System.out.println(isomorphic(s,t)); } } ```

• Guest

This solution is in efficient as you are iterating over entire Map for every single character. Why not have to maps
map1 for source –> target mapping and
map2 for target –> source mapping

• Ryan Shaw

Python solution. Passed in Leetcode OJ.
``` def is_isomorphic(a, b): """Returns true if a is isomorphic to b. It does not guarantee b is isomorphic to a.""" if a is None: return b is None if b is None: return a is None if len(a) != len(b): return False```

``` diff_map = {} for i in xrange(len(a)): c = a[i] diff = ord(a[i]) - ord(b[i]) if c in diff_map: if diff != diff_map[c]: return False else: diff_map[c] = diff return True ```

```def is_bi_isomorphic(a, b): return is_isomorphic(a, b) and is_isomorphic(b, a) ```

• Ryan Shaw

Your solution produce incorrect result for:

case: s1 = ”, s2 = ‘a’

case: s1 = ‘a’, s2 = ‘b’

• Allali Elkhalili

I think you are right, i changed the code, and i think this one work

public static boolean isIsomorphic(String s, String t) {

if (s == null || t == null)

return false;

if (s.length() != t.length())

return false;

if (s.length() == 0 && t.length() == 0)

return true;

HashMap map = new HashMap();

for (int i = 0; i < s.length(); i++) {

char c1 = s.charAt(i);

char c2 = t.charAt(i);

map.put(c1, c2);

}

for (int i = 0; i < s.length(); i++) {

char c1 = s.charAt(i);

char c2 = t.charAt(i);

List list = getKey(map, c2);

if (!list.isEmpty() && !list.contains(c1)) {

return false;

} else if (map.containsKey(c1)) {

if (c2 != map.get(c1))

return false;

}

}

return true;

}

// a method for getting key of a target value

public static List getKey(HashMap map, Character target) {

List characters = new ArrayList();

for (Map.Entry entry : map.entrySet()) {

if (entry.getValue().equals(target)) {

}

}

return characters;

}

• hive

``` public boolean isIsomorphic(String s1, String s2) { int[] m = new int[512]; for (int i = 0; i < s1.length(); i++) { System.out.println(i + " " + (s1.charAt(i)+0) + " " +(s2.charAt(i)+256)); if (m[s1.charAt(i)] != m[s2.charAt(i) + 256]) { return false; } m[s1.charAt(i)] = m[s2.charAt(i) + 256] = i + 1; } return true; } ```

• ameykelkar

``` public class Solution { public boolean isIsomorphic(String s, String t) { // Return true if both the strings are null if(s.equals("") && t.equals("")) { return true; }```

``` // Create a HashMap for one to one mapping HashMap sToT = new HashMap(); HashMap tToS = new HashMap(); ```

``` // Iterate each character for(int i = 0; i < s.length(); i++) { Character s1 = (Character) s.charAt(i); Character t1 = (Character) t.charAt(i); if(sToT.containsKey(s1) && sToT.get(s1) != t1) { return false; } else { sToT.put(s1, t1); } if(tToS.containsKey(t1) && tToS.get(t1) != s1) { return false; } else { tToS.put(t1, s1); } } return true; } } ```

• Ashwin

This also works I guess,

public static void isIsomorphic(String str1, String str2){

Set set1 = new HashSet();
Set set2 = new HashSet();

char[] charArray1 = str1.toCharArray();
char[] charArray2 = str2.toCharArray();

for(char t : charArray1){
}

for(char t : charArray2){
}

System.out.println(“size of set1 ” + set1.size());
System.out.println(“size of set2 ” + set2.size());

if(set1.size() == set2.size())
System.out.println(str1 + ” and ” + str2 + ” are Isomorphic”);
else
System.out.println(str1 + ” and ” + str2 + ” are Not Isomorphic”);

System.out.println();
}

• saurabh raj

import java.util.HashMap;
public class Isomorphic {

public boolean Check(String str1 , String str2){
if(str1 == null || str2 == null){
return false;
}
if( str1.length() != str2.length()){
return false;
}
if( ! (charAtPosition(str1).toString().equals(charAtPosition(str2).toString())) ) {
return false;
}

return true;
}

public StringBuilder charAtPosition(String str) {
HashMap hm = new HashMap();
StringBuilder charPos = new StringBuilder();
for(int i =0 ; i < str.length() ; i++) {
if( hm.containsKey(String.valueOf(str.charAt(i)))) {
charPos.append(hm.get(String.valueOf(str.charAt(i))));

} else {
hm.put(String.valueOf(str.charAt(i)), i);
charPos.append(i);
}
}
System.out.println(str + " " + charPos);

return charPos;
}

public static void main(String args[])
{
System.out.println(System.currentTimeMillis());
Isomorphic ism = new Isomorphic();

System.out.println(ism.Check("abba", "noon"));
System.out.println(System.currentTimeMillis());
}

}

• roman

if(s.length()!=t.length()) {

System.out.println(“it`s not isomorhic”);

}

for(int i=0;i<s.length();i++){

char c1=s.charAt(i);

char c2=t.charAt(i);

if(s.charAt(i)== s.charAt(i+1)){

if(t.charAt(i)==t.charAt(i+1)){

System.out.println("it's isomorphic");}

}

• This was so useful and informative about JAVA. The article helped me to learn something new. By Juliaroberts

• The question is ill-posed owing to a poor definition of isomorphic. The map needs to work both ways, otherwise foo is not isomorphic to bar, but bar is isomorphic to foo (replace b with f, and both a and r with o). In other words the mapping needed to make the changes must itself be a set isomorphism.

• Asutosh

This runs faster. (320ms)
The original solution. – 512ms.

• Asutosh

public boolean isIsomorphic(String s, String t) {

if((s.length() != t.length()) || s == null || t == null)

return false;

HashMap map = new HashMap();

for (int i = 0; i < s.length(); i++) {

char c = s.charAt(i);

char d = t.charAt(i);

if (map.containsKey(c)){

if (map.get(c) != d)

return false;

}

else {

if (!map.containsValue(d))

map.put(c, d);

else

return false;

}

}

return true;

}

• sundaram tiwari

How about we keep it simple, match the characters for repetition in both strings:

private static boolean isIsomorphic(String s, String t){
if(s == null || t == null) {
return false;
}
if(s.length() != t.length()){
return false;
}
char[] sarr = s.toCharArray();
char[] tarr = t.toCharArray();

for(int i=0; i<sarr.length; i++){
int j=i;
while (j<sarr.length-1 && sarr[j] == sarr[j+1]){
if(tarr[j] == tarr[j+1]){
j = j+1;
}else{
return false;
}
}
}
return true;
}

• Gdevice

Isn’t this one simpler? I don’t understand why do you check the key and not the value?

public boolean isIsomorphic(String s, String t) {

if (s == null || t == null)

return false;

if (s.length() != t.length())

return false;

if (s.length() == 0 && t.length() == 0)

return true;

HashMap map = new HashMap();

for (int i = 0; i < s.length(); i++) {

char c1 = s.charAt(i);

char c2 = t.charAt(i);

Character c = map.get(c1);

if (c != null && c != c2) {

return false;

} else {

map.put(c1, c2);

}

}

return true;

}