### Isomorphic Strings Without Map

Two strings are called *isomorphic* if there exists a one-to-one mapping from characters in one string to
characters in the other.

For example, "aab" and "xxy" are isomorphic, because the one-to-one mapping `{'a': 'x', 'b': 'y'}`

,
when applied to "aab", yields "xxy".
However, "acb" and "xxy" are *not* isomorphic, because the mapping `{'a': 'x', 'c': 'x', 'b': 'y'}`

is not
one-to-one, because 'x' appears twice as a value.

One way to think about it is that the mapping should allow us to transform back and forth between the two strings. After transforming "aab" to "xxy", we can invert the mapping to undo the transformation. However, after transforming "acb" to "xxy", we cannot undo the transformation.

Create a public class `IsomorphicStrings`

that provides a single public static method `areIsomorphic`

.
It accepts two `String`

s and returns `true`

if the `String`

s are isomorphic, and `false`

otherwise.
If either `String`

is `null`

, throw an `IllegalArgumentException`

.
Also note that you can begin with a simple length check to rule out certain cases.

A natural way to approach this problem is to use a `Map<Character, Character>`

.
However, this is not necessary, and is somewhat inefficient.

Instead, approach the problem this way.
At a given position i, what do we need to check for all later positions in both `String`

s?

- That if
`first[i]`

maps to`second[i]`

, then that mapping is consistent throughout the rest of the string: meaning for all j > i,`first[i] == first[j]`

->`second[i] == second[j]`

. - That there are no other mappings to
`second[i]`

.

Building of these ideas, you can solve the problem without maps or sets.
You may want to use a single `boolean[]`

to avoid rechecking the same spot in the `String`

twice.