Check if two given strings are isomorphic to each other

Two strings str1 and str2 are called isomorphic if there is a one to one mapping possible for every character of str1 to every character of str2. And all occurrences of every character in ‘str1’ map to same character in ‘str2’

Examples:

Input:  str1 = "aab", str2 = "xxy"
Output: True
'a' is mapped to 'x' and 'b' is mapped to 'y'.

Input:  str1 = "aab", str2 = "xyz"
Output: False
One occurrence of 'a' in str1 has 'x' in str2 and 
other occurrence of 'a' has 'y'.

We strongly recommend that you click here and practice it, before moving on to the solution.

A Simple Solution is to consider every character of ‘str1’ and check if all occurrences of it map to same character in ‘str2’. Time complexity of this solution is O(n*n).

An Efficient Solution can solve this problem in O(n) time. The idea is to create an array to store mappings of processed characters.

1) If lengths of str1 and str2 are not same, return false.
2) Do following for every character in str1 and str2
   a) If this character is seen first time in str1, 
      then current of str2 must have not appeared before.
      (i) If current character of str2 is seen, return false.
          Mark current character of str2 as visited.
      (ii) Store mapping of current characters.
   b) Else check if previous occurrence of str1[i] mapped
      to same character.

Below is the implementation of above idea :

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to check if two strings are isomorphic
#include<bits/stdc++.h>
using namespace std;
#define MAX_CHARS 256
  
// This function returns true if str1 and str2 are ismorphic
bool areIsomorphic(string str1, string str2)
{
  
    int m = str1.length(), n = str2.length();
  
    // Length of both strings must be same for one to one
    // corresponance
    if (m != n)
      return false;
  
    // To mark visited characters in str2
    bool marked[MAX_CHARS] = {false};
  
    // To store mapping of every character from str1 to
    // that of str2. Initialize all entries of map as -1.
    int map[MAX_CHARS];
    memset(map, -1, sizeof(map));
  
    // Process all characters one by on
    for (int i = 0; i < n; i++)
    {
        // If current character of str1 is seen first
        // time in it.
        if (map[str1[i]] == -1)
        {
            // If current character of str2 is already
            // seen, one to one mapping not possible
            if (marked[str2[i]] == true)
                return false;
  
            // Mark current character of str2 as visited
            marked[str2[i]] = true;
  
            // Store mapping of current characters
            map[str1[i]] = str2[i];
        }
  
        // If this is not first appearance of current
        // character in str1, then check if previous
        // appearance mapped to same character of str2
        else if (map[str1[i]] != str2[i])
            return false;
    }
  
    return true;
}
  
// Driver program
int main()
{
   cout << areIsomorphic("aab", "xxy") << endl;
   cout << areIsomorphic("aab", "xyz") << endl;
   return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to check if two strings are isomorphic
import java.io.*;
import java.util.*;
class Isomorphic
{
    static int size = 256;
      
    // Function returns true if str1 and str2 are ismorphic
    static boolean areIsomorphic(String str1, String str2)
    {
        int m = str1.length();
        int n = str2.length();
          
        // Length of both strings must be same for one to one
        // corresponance
        if(m != n)
            return false;
              
        // To mark visited characters in str2
        Boolean[] marked = new Boolean[size];
        Arrays.fill(marked, Boolean.FALSE);
          
        // To store mapping of every character from str1 to
        // that of str2. Initialize all entries of map as -1.
        int[] map = new int[size];
        Arrays.fill(map, -1);
          
        // Process all characters one by on
        for (int i = 0; i < n; i++)
        {
            // If current character of str1 is seen first
            // time in it.
            if (map[str1.charAt(i)] == -1)
            {
                // If current character of str2 is already
                // seen, one to one mapping not possible
                if (marked[str2.charAt(i)] == true)
                    return false;
  
                // Mark current character of str2 as visited
                marked[str2.charAt(i)] = true;
  
                // Store mapping of current characters
                map[str1.charAt(i)] = str2.charAt(i);
            }
  
            // If this is not first appearance of current
            // character in str1, then check if previous
            // appearance mapped to same character of str2
            else if (map[str1.charAt(i)] != str2.charAt(i))
            return false;
        }
  
        return true;
    }
    // driver program
    public static void main (String[] args) 
    {
        boolean res = areIsomorphic("aab", "xxy");
        System.out.println(res);
      
        res = areIsomorphic("aab", "xyz");
        System.out.println(res);
    }
}

chevron_right


Python

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python program to check if two strings are isomorphic
MAX_CHARS = 256
  
# This function returns true if str1 and str2 are isomorphic
def areIsomorphic(string1, string2):
    m = len(string1)
    n = len(string2)
  
    # Length of both strings must be same for one to one
    # corresponance
    if m != n:
        return False
  
    # To mark visited characters in str2
    marked = [False] * MAX_CHARS
  
    # To store mapping of every character from str1 to
    # that of str2. Initialize all entries of map as -1
    map = [-1] * MAX_CHARS
  
    # Process all characters one by one
    for i in xrange(n):
  
        # if current character of str1 is seen first
        # time in it.
        if map[ord(string1[i])] == -1:
  
            # if current character of st2 is already
            # seen, one to one mapping not possible
            if marked[ord(string2[i])] == True:
                return False
  
            # Mark current character of str2 as visited
            marked[ord(string2[i])] = True
  
            # Store mapping of current characters
            map[ord(string1[i])] = string2[i]
  
        # If this is not first appearance of current
        # character in str1, then check if previous
        # appearance mapped to same character of str2
        elif map[ord(string1[i])] != string2[i]:
            return False
  
    return True
  
# Driver program
print areIsomorphic("aab","xxy")
print areIsomorphic("aab","xyz")
# This code is contributed by Bhavya Jain

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to check if two 
// strings are isomorphic
using System;
  
class GFG {
      
    static int size = 256;
      
    // Function returns true if str1
    // and str2 are ismorphic
    static bool areIsomorphic(String str1, 
                              String str2)
    {
          
        int m = str1.Length;
        int n = str2.Length;
          
        // Length of both strings must be same 
        // for one to one corresponance
        if(m != n)
            return false;
              
        // To mark visited characters in str2
        bool[] marked = new bool[size];
          
        for(int i = 0; i < size; i++)
            marked[i]= false;
          
          
        // To store mapping of every character
        // from str1 to that of str2 and
        // Initialize all entries of map as -1.
        int[] map = new int[size];
          
        for(int i = 0; i < size; i++)
            map[i]= -1;
      
        // Process all characters one by on
        for (int i = 0; i < n; i++)
        {
              
            // If current character of str1 is 
            // seen first time in it.
            if (map[str1[i]] == -1)
            {
                  
                // If current character of str2
                // is already seen, one to
                // one mapping not possible
                if (marked[str2[i]] == true)
                    return false;
  
                // Mark current character of 
                // str2 as visited
                marked[str2[i]] = true;
  
                // Store mapping of current characters
                map[str1[i]] = str2[i];
            }
  
            // If this is not first appearance of current
            // character in str1, then check if previous
            // appearance mapped to same character of str2
            else if (map[str1[i]] != str2[i])
            return false;
        }
  
        return true;
    }
      
    // Driver code
    public static void Main () 
    {
        bool res = areIsomorphic("aab", "xxy");
        Console.WriteLine(res);
      
        res = areIsomorphic("aab", "xyz");
        Console.WriteLine(res);
    }
}
  
// This code is contributed by Sam007.

chevron_right


Output:

1
0

Thanks to Gaurav and Utkarsh for suggesting above approach.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above



My Personal Notes arrow_drop_up

Improved By : Sam007



Article Tags :
Practice Tags :


3


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.