问题描述
给定两个字符串 s 和 t,判断它们是否是同构的。
如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。
所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。
示例
输入: s = "egg", t = "add"
输出: true
输入: s = "foo", t = "bar"
输出: false
输入: s = "paper", t = "title"
输出: true
说明:
你可以假设 s 和 t 具有相同的长度。
分析
这题可以通过构建一个Map来做,我们可以用Map来维护一个映射。怎么映射呢?我们从s映射到t。即以s中的字符为key, 映射到以t中的字符为value。对于s中的某个字符cs, 我们对应t中的某个字符ct. 我们遍历s和t,如果map中没有这对映射,我们要判定ct是否被其他的cs所映射到,如果映射到,不符合题意(两个字符不能映射到同一个字符上)。如果没映射到,证明这是个新的合法映射,加入到Map中。
如果Map中有这对映射,我们就看一下ct是不是与映射的value相等,如果不相等,则不符合题意。(方法一)
还有种做法是分别把这两个都做到第三个映射上。如果映射出来的第三个映射不相等,则不符合题意。常见的一种映射思路是把字母第一次出现时的值记录下来。
比如abca这个串,我们就可以映射成1231。(方法二)
方法一
Java版
public boolean isIsomorphic1(String s, String t) {
Map<Character,Character> map = new HashMap<>();
for(int i = 0; i < s.length(); i++){
if(map.containsKey(s.charAt(i))){
// 包含的情况
if(map.get(s.charAt(i)) != t.charAt(i)){
return false;
}
}else{
// 不包含的情况,要判断是不是t.charAt(i)跟别人是否重复了
if(map.containsValue(t.charAt(i))){
return false;
}
map.put(s.charAt(i),t.charAt(i));
}
}
return true;
}
方法二
Java版
public boolean isIsomorphic(String s, String t){
return getCommon(s).equals(getCommon(t));
}
private String getCommon(String s){
Map<Character,Integer> map = new HashMap<>();
StringBuilder sb = new StringBuilder();
int count = 0;
for(int i = 0; i < s.length(); i++){
if(map.containsKey(s.charAt(i))){
sb.append(map.get(s.charAt(i)));
}else{
sb.append(++count);
map.put(s.charAt(i),count);
}
}
return sb.toString();
}