Given two strings s and t, determine if they are isomorphic.

Two strings s and t are isomorphic if the characters in s can be replaced to get t.

All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character, but a character may map to itself.

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 <= 5 * 104
  • t.length == s.length
  • s and t consist of any valid ascii character.

Note: This problem is from LeetCode.
โœ… Compiled
โœ… Executed
โš ๏ธ Correct
program main
    implicit none

    integer :: i, j, n
    character(len=:), allocatable :: s, t
    logical :: is_isomorphic

    ! Example 1: egg -> add
    s = 'egg'
    t = 'add'
    write(*,*) 'Example 1:'
    write(*,*) 's = ', s
    write(*,*) 't = ', t
    call solve(s, t)
    write(*,*) 'Is isomorphic? ', is_isomorphic
    write(*,*) ''

    ! Example 2: foo -> bar
    s = 'foo'
    t = 'bar'
    write(*,*) 'Example 2:'
    write(*,*) 's = ', s
    write(*,*) 't = ', t
    call solve(s, t)
    write(*,*) 'Is isomorphic? ', is_isomorphic
    write(*,*) ''

    ! Example 3: paper -> title
    s = 'paper'
    t = 'title'
    write(*,*) 'Example 3:'
    write(*,*) 's = ', s
    write(*,*) 't = ', t
    call solve(s, t)
    write(*,*) 'Is isomorphic? ', is_isomorphic
    write(*,*) ''

contains

    subroutine solve(s, t)
        implicit none
        character(len=*), intent(in) :: s, t
        logical :: is_isomorphic

        is_isomorphic = .false.

        do i = 1, len(s)
            do j = 1, len(t)
                if (s(i:i) == t(j:j)) then
                    is_isomorphic = .true.
                    exit
                end if
            end do
        end do

    end subroutine solve

end program main
โŒ Compiled
โŒ Executed
โŒ Correct
module isomorphic_strings

implicit none

contains

function is_isomorphic(s, t) result(is_iso)

character(len=*), intent(in) :: s, t
logical :: is_iso

! Initialize the mapping array
integer, parameter :: MAX_CHARS = 256
integer :: mapping(MAX_CHARS)

! Initialize the mapping array with -1
mapping = -1

! Check if the characters in s and t are isomorphic
is_iso = is_isomorphic_helper(s, t, mapping)

end function is_isomorphic

recursive function is_isomorphic_helper(s, t, mapping) result(is_iso)

character(len=*), intent(in) :: s, t
integer, intent(inout) :: mapping(:)
logical :: is_iso

! Base case: if s and t are empty, return true
if (len(s) == 0 .and. len(t) == 0) then
    is_iso = .true.
    return
endif

! Base case: if s or t is empty, return false
if (len(s) == 0 .or. len(t) == 0) then
    is_iso = .false.
    return
endif

! Check if the first character in s and t are isomorphic
if (mapping(iachar(s(1:1))) == iachar(t(1:1))) then
    is_iso = is_isomorphic_helper(s(2:), t(2:), mapping)
else
    is_iso = .false.
endif

! If the first character in s and t are not isomorphic, try mapping the first character in s to all possible characters in t
if (.not. is_iso) then
    do i = 1, len(t)
        if (mapping(iachar(s(1:1))) == -1) then
            mapping(iachar(s(1:1))) = iachar(t(i:i))
            is_iso = is_isomorphic_helper(s(2:), t, mapping)
            if (is_iso) exit
            mapping(iachar(s(1:1))) = -1
        endif
    enddo
endif

end function is_isomorphic_helper

end module isomorphic_strings

program main

use isomorphic_strings
implicit none

! Test case 1: "egg", "add"
character(len=*), parameter :: s1 = "egg"
character(len=*), parameter :: t1 = "add"

! Test case 2: "foo", "bar"
character(len=*), parameter :: s2 = "foo"
character(len=*), parameter :: t2 = "bar"

! Test case 3: "paper", "title"
character(len=*), parameter :: s3 = "paper"
character(len=*), parameter :: t3 = "title"

! Test case 4: "ab", "ba"
character(len=*), parameter :: s4 = "ab"
character(len=*), parameter :: t4 = "ba"

! Test case 5: "aa", "ab"
character(len=*), parameter :: s5 = "aa"
character(len=*), parameter :: t5 = "ab"

! Test case 6: "aa", "aa"
character(len=*), parameter :: s6 = "aa"
character(len=*), parameter :: t6 = "aa"

! Test case 7: "aab", "aba"
character(len=*), parameter :: s7 = "aab"
character(len=*), parameter :: t7 = "aba"

! Test case 8: "abc", "bca"
character(len=*), parameter :: s8 = "abc"
character(len=*), parameter :: t8 = "bca"

! Test case 9: "abcd", "dabc"
character(len=*), parameter :: s9 = "abcd"
character(len=*), parameter :: t9 = "dabc"

! Test case 10: "abcd", "bacd"
character(len=*), parameter :: s10 = "abcd"
character(len=*), parameter :: t10 = "bac
๐ŸŒ Data from online sources
def is_isomorphic(s: str, t: str) -> bool:
    map1, map2 = {}, {}
    for char_s, char_t in zip(s, t):
        if char_s not in map1:
            map1[char_s] = char_t
        if char_t not in map2:
            map2[char_t] = char_s
        if map1[char_s] != char_t or map2[char_t] != char_s:
            return False
    return True
  • Create two maps (or hash_maps) to store the mappings for characters in s to t and characters in t to s.
  • Iterate through the characters of s and t.
  • If the current character of s is not a key in the first map, add it with the corresponding character of t as the value.
  • If the current character of t is not a key in the second map, add it with the corresponding character of s as the value.
  • If the maps have inconsistent mappings, return false (they are not isomorphic).
  • If the loop is over without finding inconsistent mappings, return true (the strings are isomorphic).
๐ŸŒ Data from online sources
#include <unordered_map>

bool isIsomorphic(std::string s, std::string t) {
    std::unordered_map<char, char> map1, map2;
    for (size_t i = 0; i < s.size(); ++i) {
        if (map1.find(s[i]) == map1.end()) {
            map1[s[i]] = t[i];
        }
        if (map2.find(t[i]) == map2.end()) {
            map2[t[i]] = s[i];
        }
        if (map1[s[i]] != t[i] || map2[t[i]] != s[i]) {
            return false;
        }
    }
    return true;
}
  • Create two maps (or hash_maps) to store the mappings for characters in s to t and characters in t to s.
  • Iterate through the characters of s and t.
  • If the current character of s is not a key in the first map, add it with the corresponding character of t as the value.
  • If the current character of t is not a key in the second map, add it with the corresponding character of s as the value.
  • If the maps have inconsistent mappings, return false (they are not isomorphic).
  • If the loop is over without finding inconsistent mappings, return true (the strings are isomorphic).