Detecting if two given strings are isomorphic using Java data structures So I have written the following code and it works for various same length isomorphic strings I have tried. However I am not sure what are some time complexity improvements and coding tweaks that could be applied to the code:

/**
 * Created by mona on 5/26/16.
 */
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Collections;

public class IsomorphicStrings {
    //the words "abca" and "zbxz" are isomorphic
    //aabc a(2) b(1) c(1)
    //zzbx z(2) b(1) x(1)
    //my algorithm
    //create a sorted hashmap  on value
    //check to see if two hashmap are equal based on their value set
    //assuming two isomorphic strings are of the same length

    public static boolean areIsomorphic(String s1, String s2) {
        Map&lt;Character, Integer&gt; freqMap1 = new HashMap&lt;&gt;();
        Map&lt;Character, Integer&gt; freqMap2 = new HashMap&lt;&gt;();

        for (int i=0; i&lt;s1.length(); i++) {
            if (freqMap1.containsKey(s1.charAt(i))) {
                int freq1 = freqMap1.get(s1.charAt(i));
                freqMap1.put(s1.charAt(i), freq1 + 1);
            } else {
                freqMap1.put(s1.charAt(i), 1);
            }

        }

        for (int i=0; i&lt;s2.length(); i++) {
            if (freqMap2.containsKey(s2.charAt(i))) {
                int freq2 = freqMap2.get(s2.charAt(i));
                freqMap2.put(s2.charAt(i), freq2 + 1);
            }
            else {
                freqMap2.put(s2.charAt(i), 1);
            }

        }

        List&lt;Integer&gt; freqList1 = new ArrayList&lt;&gt;();
        List&lt;Integer&gt; freqList2 = new ArrayList&lt;&gt;();

        for (Map.Entry entry: freqMap1.entrySet()) {
            freqList1.add((Integer) entry.getValue());
        }

        for (Map.Entry entry: freqMap2.entrySet()) {
            freqList2.add((Integer) entry.getValue());
        }

        Collections.sort(freqList1);
        Collections.sort(freqList2);

        return freqList1.equals(freqList2);

    }

    public static void main(String[] args) {
        String s1="abca";
        String s2="zbxz";
        System.out.println(areIsomorphic(s1, s2));
    }
}


/* side note: can isomorphic strings be of different lengths? Then what algorithm do you suggest? */
Your build two HashMap&lt;Character, Integer&gt;, then two ArrayList&lt;Integer&gt;, then sort the lists, then compare the lists.  Your logic is too complicated, I think.  Furthermore, you aren't taking advantage of the symmetry in the problem — nearly every line of code appears in duplicate. Even worse, the code doesn't even do what you claim; rather, it tests whether the inputs are isomorphic anagrams of each other.

Going by the definition, we can just build a character-to-character map from one string to the other, and fail as soon as we encounter an unexpected character.  This should be O(n), and possibly faster if a mismatch is detected early.

The code works equally well on any pair of CharSequences, not just Strings, so we might as well generalize.

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

public class IsomorphicStrings {
    public static boolean areIsomorphic(CharSequence s1, CharSequence s2) {
        return isSurjective(s1, s2) &amp;&amp; isSurjective(s2, s1);
    }

    private static boolean isSurjective(CharSequence s1, CharSequence s2) {
        if (s1.length() != s2.length()) return false;

        Map&lt;Character, Character&gt; surjection = new HashMap&lt;&gt;();
        for (int i = 0; i &lt; s1.length(); i++) {
            char c1 = s1.charAt(i);
            char c2 = s2.charAt(i);
            Character prev = surjection.put(c1, c2);
            if (prev != null &amp;&amp; prev != c2) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        System.out.println(areIsomorphic(args[0], args[1]));
    }
}