题目:
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.
链接: http://leetcode.com/problems/isomorphic-strings/
题解:
一开始的想法就是使用HashMap,试了一下发现必须一一对应,所以想到了类似电话簿,建立两个hashmap来保存这种一一对应的关系。
Time Complexity - O(n), Space Complexity - O(1)。
public class Solution { public boolean isIsomorphic(String s, String t) { if(s == null || t == null || s.length() != t.length()) return false; Map<Character, Character> st = new HashMap<>(); Map<Character, Character> ts = new HashMap<>(); for(int i = 0; i < s.length(); i++) { if(!st.containsKey(s.charAt(i))) { st.put(s.charAt(i), t.charAt(i)); } else { if(st.get(s.charAt(i)) != t.charAt(i)) return false; } if(!ts.containsKey(t.charAt(i))) { ts.put(t.charAt(i), s.charAt(i)); } else { if(ts.get(t.charAt(i)) != s.charAt(i)) return false; } } return true; } }
还有更好的写法,就是开一个到两个array,然后比较ASCII,这样应该能算是O(1)和O(1)。二刷要多学习。
二刷:
使用GrandYong的写法,使用两个bitmap,然后存储sChar和tChar的位置, 注意 sMap[sChar] = i + 1和tMap[tChar] = i +1是为了区别初始的0。假如我们初始化数组都等于-1的话,就可以不用+1。不过这个也无关紧要
Java:
Time Complexity - O(n), Space Complexity - O(1)。
public class Solution { public boolean isIsomorphic(String s, String t) { if (s == null || t == null || s.length() != t.length()) { return false; } int[] sMap = new int[256], tMap = new int[256]; for (int i = 0; i < s.length(); i++) { char sChar = s.charAt(i); char tChar = t.charAt(i); if (sMap[sChar] != tMap[tChar]) { return false; } sMap[sChar] = i + 1; // to differential case 0, 0 tMap[tChar] = i + 1; } return true; } }
三刷:
Java:
对Unicode还是要用两个hashMap。 Space Complexity, 即使是Unicode也只是小常数,所以还是算O(1)。
Time Complexity - O(n), Space Complexity - O(1)。
public class Solution { public boolean isIsomorphic(String s, String t) { if (s == null || t == null || s.length() != t.length()) { return false; } Map<Character, Character> st = new HashMap<>(); Map<Character, Character> ts = new HashMap<>(); for (int i = 0; i < s.length(); i++) { char sChar = s.charAt(i); char tChar = t.charAt(i); if ((st.containsKey(sChar) && st.get(sChar) != tChar) || (ts.containsKey(tChar) && ts.get(tChar) != sChar)) { return false; } if (!st.containsKey(sChar)) { st.put(sChar, tChar); } if (!ts.containsKey(tChar)) { ts.put(tChar, sChar); } } return true; } }
假设Alphabet为Single-byte char,我们就可以使用bitmap,速度大大提高。这里是对每个元素的出现位置进行比较,并且使用的是 1- based index来避免 array数组初始化的0。每次遇到两个字符,我们就去sMap和tMap中来比较它们上一次的出现的位置是否相同,假如不通的话我们就返回false。
Time Complexity - O(n), Space Complexity - O(1)。
public class Solution { public boolean isIsomorphic(String s, String t) { if (s == null || t == null || s.length() != t.length()) { return false; } int[] sMap = new int[256]; int[] tMap = new int[256]; for (int i = 0; i < s.length(); i++) { char sChar = s.charAt(i); char tChar = t.charAt(i); if (sMap[sChar] != tMap[tChar]) { return false; } sMap[sChar] = i + 1; tMap[tChar] = i + 1; } return true; } }
Reference:
https://leetcode.com/discuss/33889/short-java-solution-without-maps
https://leetcode.com/discuss/55777/fast-java-solution-using-ascii-code