Isomorphic Strings
- Easy
- tag: String, HashMap, ASCII
- Similar: word pattern, Bulls & Cows
Given two strings s and t, determine if they are isomorphic.
- Two strings 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.
- For example,
- Given "egg", "add", return true.
- Given "foo", "bar", return false.
- Given "paper", "title", return true.
- Given "aa", "ab", return false.
思路
- 简单的就是记录所有mapping记录, 然后比较有没有不符合mapping的. 注意这里是1-1映射, 但是并不是"a->b" => "b->a". 例如"ab"->"bc".
- 由于规定了是ASCII, 所以用256个元素的array也可以.
idea 1 : 使用map, 但是第27个test case出错!
- 记录每一个mapping, 只要发现不match就return false.
- 代码如下:
public boolean isIsomorphic(String s, String t) {
Map<Character, Character> map = new HashMap<>();
for (int i = 0; i < s.length(); ++i) {
char a = s.charAt(i);
char b = t.charAt(i);
if (!map.containsKey(a)) {
map.put(a,b);
}
else {
if (map.get(a) != b) {
return false;
}
}
}
return true;
}
- 但是上面的代码会在"ab","aa"报错.我直接返回true了, 因为b->a并没有报错. 而事实上,由于是1-1映射, 所以不应该有a/b都map到a的. 所以就是每次有新的mapping, 都检查一下映射值是否用过了. 若用过, 说明有其他数map到这个映射值了.
- 所以修改了以上代码如下:
public boolean isIsomorphic(String s, String t) {
Map<Character, Character> map = new HashMap<>();
for (int i = 0; i < s.length(); ++i) {
char a = s.charAt(i);
char b = t.charAt(i);
if (!map.containsKey(a)) {
if (map.containsValue(b)) {
return false;
}
map.put(a,b);
}
else {
if (map.get(a) != b) {
return false;
}
}
}
return true;
}
idea 2
- 由于是固定的ASCII只有256个. 所以总共是512. (因为s, t各用256个). 然后建立1-1映射关系.
- 代码如下:
public boolean isIsomorphic(String s, String t) {
int[] map = new int[512];
for (int i = 0; i < s.length(); ++i) {
if (map[s.charAt(i)] != map[t.charAt(i) + 256]) return false;
map[s.charAt(i)] = map[t.charAt(i) + 256] = i + 1;
}
return true;
}