I am working on the LeetCode problem Isomorphic Strings:
Given two strings
s
andt
, determine if they are isomorphic.Two strings
s
andt
are isomorphic if the characters ins
can be replaced to gett
.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
andt
consist of any valid ascii character.
I have most of the tests working correctly I am just failing some tests.
This is what I have so far:
import java.nio.charset.*;
class Solution {
public static boolean isIsomorphic(String s, String t) {
s = s.toLowerCase();
t = t.toLowerCase();
int matchCount1 = 0;
int matchCount2 = 0;
matchCount1 = checkMatching(s);
matchCount2 = checkMatching(t);
System.out.print(matchCount1);
System.out.print(matchCount2);
return matchCount1 == matchCount2;
}
public static int checkMatching(String s) {
int count = 0;
int j = 0;
for (int i = 0; i < s.length(); i ) { // s.length == 4
char current = s.charAt(i); // current = 'p'
j = 1;
while (j < s.length() - 1) {
if (current == s.charAt(j)) { // if p != a
count = 1;
break;
} else {
j ; // j == 2
}
}
}
return count;
}
public static void main(String[] args) {
String s = "paper";
String t = "title";
isIsomorphic(s, t);
}
}
Failing test:
If the strings s = "foo"
and t = "bar"
, the counts for both return 0
, where the answer should be 1
and 0
as "foo"
contains two "o"
characters.
Any help would be appreciated as I feel like I'm one small change away.
CodePudding user response:
Basically what this task required is to determine whether the two Strings have identical structure, i.e. if string s
contains character 'a'
at indices 1, 3, 8
, we expect string t
to have identical character (of whatever kind) at indices 1, 3, 8
and this character shouldn't be encountered anywhere else in the t
. It this holds true for every character - the String are isomorphic.
We can find out it in a linear time O(n) by indexing positions of every character in a Map for both strings. It would be a map of type Map<Character,List<Integer>>
, which associates a character with its indices.
And then we need to find out if all combinations indices of these strings match. For that, we can dump the Values of each Map into a HashSet
, it would be a set of type Set<List<Integer>>
. And compare these sets using Set.equals()
(reminder: two sets are equal if they contain the same elements, regardless of their order).
That's how implementation might look like:
public static boolean isIsomorphic(String s, String t) {
if (s.length() != t.length()) return false; // early kill, if length of these string is not equal they are not isomorphic
String first = s.toLowerCase();
String second = t.toLowerCase();
Set<List<Integer>> positions1 = getPositions(first);
Set<List<Integer>> positions2 = getPositions(second);
return positions1.equals(positions2);
}
public static Set<List<Integer>> getPositions(String str) {
Map<Character, List<Integer>> positionsByCharacter = new HashMap<>();
for (int i = 0; i < str.length(); i ) {
char next = str.charAt(i);
positionsByCharacter
.computeIfAbsent(next, k -> new ArrayList<>())
.add(i);
}
return new HashSet<>(positionsByCharacter.values());
}
main()
public static void main(String[] args) {
System.out.println(isIsomorphic("egg", "add"));
System.out.println(isIsomorphic("foo", "bar"));
System.out.println(isIsomorphic("paper", "title"));
}
Output:
true
false
true