题目描述(传送门)
给定两个字符串 s 和 t,判断它们是否是同构的。
如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。
所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。
示例
示例 1:
输入: s = "egg", t = "add"
输出: true
示例 2:
输入: s = "foo", t = "bar"
输出: false
示例 3:
输入: s = "paper", t = "title"
输出: true
解题思路
一个错误示例
首先题目说的是字符,所以一定要注意不只是只有字母,而应该是各种字符,我们来看看ASICC码表。
在这里总共是有128个字符的,在数组初始化时我们应该大小为128而不是26.
我们初始化两个大小为128的数组,然后遍历两个字符串,然后统计每个字符,然后在数组里边都加1.判断字符串对应位置时,数组中的大小。
public boolean isIsomorphic(String s, String t) {
int[] sarray = new int[128];
int[] tarray = new int[128];
if (s.length() != t.length()) {
return false;
}
for (int i = 0; i < s.length(); i++) {
if (sarray[s.charAt(i)] != tarray[t.charAt(i)]) {
return false;
}
sarray[s.charAt(i)] ++;
tarray[t.charAt(i)] ++;
}
return true;
}
这样看来示例一是没有问题的,但是提交就不能完全通过。
比如这个
s = “aba”
t = “baa”
这里判断他们的个数一直都是相同的,所以返回了ture而正确的应该返回false。
这是因为前两次ab和ba导致前一步是如下所示:
正确思路
每次都加1,不能够区分是那一次循环操作的。如果将每次循环加的数不同但是两个数组对应字符的位置加相同的数字就可解决这个问题。
因此我们只需要在每次循环时,加上一个变化的值而且不重复,我们可以单独定义一个值,但是循环之中i的值就一直就在变换,而且不重复一次加上i就可以了。
实现代码
public boolean isIsomorphic(String s, String t) {
int[] sarray = new int[128];
int[] tarray = new int[128];
if (s.length() != t.length()) {
return false;
}
for (int i = 0; i < s.length(); i++) {
if (sarray[s.charAt(i)] != tarray[t.charAt(i)]) {
return false;
}
sarray[s.charAt(i)] = i + 1 ;
tarray[t.charAt(i)] = i + 1;
}
return true;
}
考虑到i从0开始,区分度不够。所以在加1,在这里1可以随便换。
HashMap
在这里使用两张HashMap,具体看代码,不在解释。
public boolean isIsomorphic(String s, String t) {
Map<Character, Character> s2t = new HashMap<Character, Character>();
Map<Character, Character> t2s = new HashMap<Character, Character>();
int len = s.length();
for (int i = 0; i < len; ++i) {
char x = s.charAt(i), y = t.charAt(i);
if ((s2t.containsKey(x) && s2t.get(x) != y) || (t2s.containsKey(y) && t2s.get(y) != x)) {
return false;
}
s2t.put(x, y);
t2s.put(y, x);
}
return true;
}