题目地址:https://leetcode.com/problems/isomorphic-strings/
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.
Note:
You may assume both s and t have the same length.
题目要看看两个字符串是不是一种模式,一个字符串中的字符被另一个长度相同的相对应位置的字符替换以后,两个字符串是相同的。
我们可以这么想,假如两个字符串有相同的模式的话,那么相同的字符相对应的字符之间的距离是相同的,什么意思呢,如图所示:
步骤如下:
- 两个字符串s,t从第一个字符同步开始扫描,然后计算字符之间的“距离”;
- 检查map表,如果这个字符已经算过了,那么现在算出的距离就要跟以前的做比较,如果距离相同那么继续往下扫描字符串,如果不相同,说明这两个字符串的模式不同,返回false。
- 检查map表,如果发现这个字符的距离还没添加过,那么要添加到map中,继续扫描,s中的当前字符作为key,t中当前字符的的ASCII码减去s中当前字符的ASCII码得到的整数作为value,即距离;
- 如果两个字符串都扫描完了也没返回false,那么说明字符串s相对于字符串t是相同的模式。
这里为什么说是“s相对于字符串t是的模式”,因为我们从题意可知,两个字符串交换位置,得到的结果应该是不变的,但是上述算法不能保证这一点,所以我们用“相对于”来表述。
比如下面例子:
input: "ab" "aa"
output: false
这个例子显然是输出false的,但是按照上述步骤,则输出的就是true,如果输入反过来,那么结果就变了:
input: "aa" "ab"
output: true
为了避免这样的错误,我们可以将两个字符串交换位置再次作比较,两次得到的结果去且关系,那么就是整个方法的结果:
public class IsomorphicStrings {
public static boolean _isIsomorphic(String s, String t) {
if (s == null && t == null)
return true;
if (s == null || t == null)
return false;
HashMap<Character, Integer> dist = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
if (!dist.containsKey(s.charAt(i))){
dist.put(s.charAt(i), t.charAt(i) - s.charAt(i));
} else {
if (dist.get(s.charAt(i)) != t.charAt(i) - s.charAt(i))
return false;
else
continue;
}
}
return true;
}
public static boolean isIsomorphic(String s, String t) {
return _isIsomorphic(s, t) && _isIsomorphic(t, s);
}
public static void main(String[] args) {
System.out.println(isIsomorphic("ab", "aa"));
}
}