Isomorphic Strings – Leetcode Java | Welkin Lan
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
Given
Given
X. Normalize
https://blog.csdn.net/NoMasp/article/details/50611168
翻译完这题目就很自然的想到一个方法,我希望将字符串全部输出成数字序列:
For example,
Given "paper", return "01023".
Given "foo", return "011".
Given "isomorphic", return "0123245607".
X.
https://leetcode.com/problems/isomorphic-strings/discuss/57802/Java-solution-using-HashMap
X.
https://segmentfault.com/a/1190000016865879
https://discuss.leetcode.com/topic/13001/short-java-solution-without-maps
X. http://www.cnblogs.com/grandyang/p/4465779.html
根据一对一映射的特点,我们需要用两个哈希表分别来记录原字符串和目标字符串中字符出现情况,由于ASCII码只有256个字符,所以我们可以用一个256大小的数组来代替哈希表,并初始化为0,我们遍历原字符串,分别从源字符串和目标字符串取出一个字符,然后分别在两个哈希表中查找其值,若不相等,则返回false,若想等,将其值更新为i + 1
We could use extra space – hashtable to save mapped values and check time is O(1)
https://segmentfault.com/a/1190000003709248
public boolean isIsomorphic(String s, String t) {
A simple HashMap<s.char, t.char> question, only rule is that No two characters may map to the same character.
We could use map.containsValue() => O(n) time to check whether value is existed
http://www.programcreek.com/2014/05/leetcode-isomorphic-strings-java/
- Not efficient
public boolean isIsomorphic(String s, String t) {
https://sisijava.wordpress.com/2015/05/05/leetcode-isomorphic-strings/
X. http://www.cnblogs.com/easonliu/p/4465650.html
就是记录遍历s的每一个字母,并且记录s[i]到t[i]的映射,当发现与已有的映射不同时,说明无法同构,直接return false。但是这样只能保证从s到t的映射,不能保证从t到s的映射,所以交换s与t的位置再重来一遍上述的遍历就OK了。
X.
http://likesky3.iteye.com/blog/2237360
思路1:维护两个哈希表,char[] map, boolean[] used, 长度均为256,map[charS] = charT, 表示将字符charS 映射为charT, used[charT]==true 表示charT已经被某个字符映射过了。同步遍历字符串s & t,记两者当前的字符分别为charS, charT, 若charS是新字符,且charT没有被使用,则我们可将其同charT建立映射关系,否则说明有两个不同的字符试图映射到同一个字符上,不符合要求;若charS已被建立映射关系,则检查charT是否和charS的映射字符相等,不相等不符合题目要求的“All occurrences of a character must be replaced with another character ”。
思路2:参考https://leetcode.com/discuss/33854/my-6-lines-solution,又是一个怎巧妙了得~ 这个思路也是用两个哈希表,不同于思路1直接将s中的字符映射到t中字符,它是将s 和 t中的字符同时映射到下标上,因为若个字符若存在映射关系,则必然是出现在相同的下标位置,实现中由于初始值为0,建立映射时使用 i + 1,以区分未映射状态和映射到下标为0的状态。
public boolean isIsomorphic(String s, String t) { char[] map1 = new char[256], map2 = new char[256]; for (int i = 0; i < s.length(); i++) { char a = s.charAt(i); char b = t.charAt(i); if (!this.map(a, b, map1) || !this.map(b, a, map2)) { return false; } } return true; } private boolean map(char a, char b, char[] map) { if (map[a] == 0) { map[a] = b; } return map[a] == b; }
public boolean isIsomorphic(String s1, String s2) {
int[] m = new int[512];
for (int i = 0; i < s1.length(); i++) {
if (m[s1.charAt(i)] != m[s2.charAt(i)+256]) return false;
m[s1.charAt(i)] = m[s2.charAt(i)+256] = i+1;
}
return true;
}
public boolean isIsomorphic(String s, String t) {
int[] map = new int[128];
int[] book = new int[128];
for (int i = 0; i < s.length(); i++) {
int cs = (int) s.charAt(i);
int ts = (int) t.charAt(i);
if (map[cs] == 0 && book[ts] == 0) {
map[cs] = ts;
book[ts] = 1;
} else if (map[cs] != ts)
return false;
}
return true;
}
https://leetcode.com/discuss/33854/my-6-lines-solution
bool isIsomorphic(string s, string t) { int m1[256] = {0}, m2[256] = {0}, n = s.size(); for (int i = 0; i < n; ++i) { if (m1[s[i]] != m2[t[i]]) return false; m1[s[i]] = i + 1; m2[t[i]] = i + 1; } return true; }
Read full article from Isomorphic Strings – Leetcode Java | Welkin Lan
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.X. Normalize
https://blog.csdn.net/NoMasp/article/details/50611168
翻译完这题目就很自然的想到一个方法,我希望将字符串全部输出成数字序列:
For example,
Given "paper", return "01023".
Given "foo", return "011".
Given "isomorphic", return "0123245607".
private ArrayList getArrayOrder(String str) {
HashMap<Character, Integer> strM = new HashMap<>();
int index = 0;
ArrayList order = new ArrayList(str.length());
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (strM.containsKey(c)) {
order.add(strM.get(c));
} else {
strM.put(c, index);
order.add(index);
index += 1;
}
}
return order;
}
public boolean isIsomorphic(String s, String t) {
if (s.length() != t.length())
return false;
ArrayList s0 = getArrayOrder(s), t0 = getArrayOrder(t);
for (int i = 0; i < s0.size(); i++)
if (s0.get(i) != t0.get(i))
return false;
return true;
}
X.
https://leetcode.com/problems/isomorphic-strings/discuss/57802/Java-solution-using-HashMap
Check twice with helper method. O(n) time and O(n) space.
public boolean isIsomorphic(String s, String t) {
if(s == null && t == null) return true;
else if(s == null || t == null) return false;
if(s.length() != t.length()) return false;
return helper(s,t) && helper(t,s);
}
private boolean helper(String s, String t){
Map<Character,Character> map = new HashMap<>();
for(int i = 0;i<s.length();i++){
if(!map.containsKey(s.charAt(i))){
map.put(s.charAt(i),t.charAt(i));
}else{
if(map.get(s.charAt(i)) != t.charAt(i) ) return false;
}
}
return true;
}
X.
https://segmentfault.com/a/1190000016865879
public boolean isIsomorphic(String s, String t) {
int[] stmap = new int[256];
int[] tsmap = new int[256];
Arrays.fill(stmap, -1);
Arrays.fill(tsmap, -1);
for (int i = 0; i < s.length(); i++) {
if (stmap[s.charAt(i)] != tsmap[t.charAt(i)]) return false;
stmap[s.charAt(i)] = i;
tsmap[t.charAt(i)] = i;
}
return true;
}
The main idea is to store the last seen positions of current (i-th) characters in both strings. If previously stored positions are different then we know that the fact they're occuring in the current i-th position simultaneously is a mistake. We could use a map for storing but as we deal with chars which are basically ints and can be used as indices we can do the whole thing with an array.
public boolean isIsomorphic(String s1, String s2) {
int[] m = new int[512];
for (int i = 0; i < s1.length(); i++) {
if (m[s1.charAt(i)] != m[s2.charAt(i)+256]) return false;
m[s1.charAt(i)] = m[s2.charAt(i)+256] = i+1;
}
return true;
}
根据一对一映射的特点,我们需要用两个哈希表分别来记录原字符串和目标字符串中字符出现情况,由于ASCII码只有256个字符,所以我们可以用一个256大小的数组来代替哈希表,并初始化为0,我们遍历原字符串,分别从源字符串和目标字符串取出一个字符,然后分别在两个哈希表中查找其值,若不相等,则返回false,若想等,将其值更新为i + 1
bool isIsomorphic(string s, string t) { int m1[256] = {0}, m2[256] = {0}, n = s.size(); for (int i = 0; i < n; ++i) { if (m1[s[i]] != m2[t[i]]) return false; m1[s[i]] = i + 1; m2[t[i]] = i + 1; } return true; }X.
We could use extra space – hashtable to save mapped values and check time is O(1)
https://segmentfault.com/a/1190000003709248
用一个哈希表记录字符串s中字母到字符串t中字母的映射关系,一个集合记录已经映射过的字母。或者用两个哈希表记录双向的映射关系。这里不能只用一个哈希表,因为要排除egg->ddd这种多对一的映射。
public boolean isIsomorphic(String s, String t) {
HashMap<Character,Character> map = new HashMap<>();
HashSet<Character> mapped = new HashSet<>();
for (int i=0; i<s.length(); i++){
if (map.containsKey(s.charAt(i))){
if (t.charAt(i)==map.get(s.charAt(i))) continue;
else return false;
}
else if (mapped.contains(t.charAt(i))) return false;
map.put(s.charAt(i),t.charAt(i));
mapped.add(t.charAt(i));
}
return true;
}
A:A simple HashMap<s.char, t.char> question, only rule is that No two characters may map to the same character.
We could use map.containsValue() => O(n) time to check whether value is existed
http://www.programcreek.com/2014/05/leetcode-isomorphic-strings-java/
- Not efficient
public boolean isIsomorphic(String s, String t) {
HashMap<Character,Character> map = new HashMap<>();
for (int i=0; i<s.length(); i++){
if (map.containsKey(s.charAt(i))){
if (t.charAt(i)==map.get(s.charAt(i))) continue;
else return false;
}
else if (map.containsValue(t.charAt(i))) return false;
map.put(s.charAt(i),t.charAt(i));
}
return true;
}
https://sisijava.wordpress.com/2015/05/05/leetcode-isomorphic-strings/
public
boolean
isIsomorphic(String s, String t) {
if
(s ==
null
&& t ==
null
){
return
true
;
}
else
if
(s ==
null
||t ==
null
){
return
false
;
}
else
{
if
(s == t){
return
true
;
}
else
{
if
(s.length() != t.length()){
return
false
;
}
else
{
int
l = s.length();
HashMap<Character, Character> a =
new
HashMap<Character, Character>();
HashMap<Character, Character> b =
new
HashMap<Character, Character>();
for
(
int
i =
0
; i < l; i++){
char
sc = s.charAt(i);
char
tc = t.charAt(i);
if
(!a.containsKey(tc) && !b.containsKey(sc)){
a.put(tc, sc);
b.put(sc, tc);
}
else
{
if
(a.containsKey(tc) ? a.get(tc)!=sc : b.get(sc)!=tc)
return
false
;
}
}
}
}
}
return
true
;
}
就是记录遍历s的每一个字母,并且记录s[i]到t[i]的映射,当发现与已有的映射不同时,说明无法同构,直接return false。但是这样只能保证从s到t的映射,不能保证从t到s的映射,所以交换s与t的位置再重来一遍上述的遍历就OK了。
bool isIsomorphic(string s, string t) { 4 if (s.length() != t.length()) return false; 5 map<char, char> mp; 6 for (int i = 0; i < s.length(); ++i) { 7 if (mp.find(s[i]) == mp.end()) mp[s[i]] = t[i]; 8 else if (mp[s[i]] != t[i]) return false; 9 } 10 mp.clear(); 11 for (int i = 0; i < s.length(); ++i) { 12 if (mp.find(t[i]) == mp.end()) mp[t[i]] = s[i]; 13 else if (mp[t[i]] != s[i]) return false; 14 } 15 return true; 16 }http://www.cnblogs.com/zhuli19901106/p/4469153.html
6 bool isIsomorphic(string s, string t) { 7 return check(s, t) && check(t, s); 8 } 9 private: 10 bool check(string s, string t) { 11 char a[256]; 12 13 memset(a, 0, sizeof(a)); 14 int i; 15 int n = s.length(); 16 17 for (i = 0; i < n; ++i) { 18 if (a[s[i]] == 0) { 19 a[s[i]] = t[i]; 20 } 21 s[i] = a[s[i]]; 22 } 23 24 return s == t; 25 }http://www.zhuangjingyang.com/leetcode-isomorphic-strings/
X.
http://likesky3.iteye.com/blog/2237360
思路1:维护两个哈希表,char[] map, boolean[] used, 长度均为256,map[charS] = charT, 表示将字符charS 映射为charT, used[charT]==true 表示charT已经被某个字符映射过了。同步遍历字符串s & t,记两者当前的字符分别为charS, charT, 若charS是新字符,且charT没有被使用,则我们可将其同charT建立映射关系,否则说明有两个不同的字符试图映射到同一个字符上,不符合要求;若charS已被建立映射关系,则检查charT是否和charS的映射字符相等,不相等不符合题目要求的“All occurrences of a character must be replaced with another character ”。
思路2:参考https://leetcode.com/discuss/33854/my-6-lines-solution,又是一个怎巧妙了得~ 这个思路也是用两个哈希表,不同于思路1直接将s中的字符映射到t中字符,它是将s 和 t中的字符同时映射到下标上,因为若个字符若存在映射关系,则必然是出现在相同的下标位置,实现中由于初始值为0,建立映射时使用 i + 1,以区分未映射状态和映射到下标为0的状态。
- // Method 2 https://leetcode.com/discuss/33854/my-6-lines-solution
- public boolean isIsomorphic(String s, String t) {
- int[] map1 = new int[256];
- int[] map2 = new int[256];
- for (int i = 0; i < s.length(); i++) {
- if (map1[s.charAt(i)] != map2[t.charAt(i)])
- return false;
- map1[s.charAt(i)] = i + 1;
- map2[t.charAt(i)] = i + 1;
- }
- return true;
- }
- // Method 1
- public boolean isIsomorphic1(String s, String t) {
- if (s == null || t == null) return false;
- char[] map = new char[256];
- boolean[] used = new boolean[256];
- for (int i = 0; i < s.length(); i++) {
- char charS = s.charAt(i);
- char charT = t.charAt(i);
- if (map[charS] == 0) {
- if (used[charT]) return false; // No two characters may map to the same character
- map[charS] = charT;
- used[charT] = true;
- } else if (map[charS] != charT){
- return false; // All occurrences of a character must be replaced with another character
- }
- }
- return true;
- }
public boolean isIsomorphic(String s, String t) { char[] map1 = new char[256], map2 = new char[256]; for (int i = 0; i < s.length(); i++) { char a = s.charAt(i); char b = t.charAt(i); if (!this.map(a, b, map1) || !this.map(b, a, map2)) { return false; } } return true; } private boolean map(char a, char b, char[] map) { if (map[a] == 0) { map[a] = b; } return map[a] == b; }
The problem is that a
char
in Java takes up two bytes. Since the inputs are not limited to ASCII strings in the question, you may have two char[65536] for this solution.https://leetcode.com/discuss/33854/my-6-lines-solution
bool isIsomorphic(string s, string t) { int m1[256] = {0}, m2[256] = {0}, n = s.size(); for (int i = 0; i < n; ++i) { if (m1[s[i]] != m2[t[i]]) return false; m1[s[i]] = i + 1; m2[t[i]] = i + 1; } return true; }
X. 在这里面我用了两个HashMap,一个HashMap用来记s的字符到t的映射,用于判断s中的两个字符不能用t中的同一个字符替换,另一个HashMap用来记t的字符到s的映射,用于判断t中的两个字符不能由s中同一个字符映射而来
http://my.oschina.net/Tsybius2014/blog/489587
public
boolean
isIsomorphic(String s, String t) {
if
(s.length() != t.length()) {
return
false
;
}
HashMap<Character, Character> hashMapS =
new
HashMap<Character, Character>();
HashMap<Character, Character> hashMapT =
new
HashMap<Character, Character>();
for
(
int
i =
0
; i < s.length(); i++) {
if
(hashMapS.containsKey(s.charAt(i))) {
if
(hashMapS.get(s.charAt(i)) != t.charAt(i)) {
return
false
;
}
}
else
{
if
(hashMapT.containsKey(t.charAt(i))) {
return
false
;
}
hashMapS.put(s.charAt(i), t.charAt(i));
hashMapT.put(t.charAt(i), s.charAt(i));
}
}
return
true
;
}
}
public
boolean
isIsomorphic(String s, String t) {
if
(s.length() != t.length()) {
return
false
;
}
//虽然不考虑英文大小写,但因为不仅仅有26个英文字母,还可能有其他符号,所以数组要开得足够大
int
len =
40
;
//这里数组长度开到40,可以满足题目AC
char
[] charInS =
new
char
[len];
char
[] charInT =
new
char
[len];
for
(
int
i =
0
; i < len; i++) {
charInS[i] =
'0'
;
charInT[i] =
'0'
;
}
boolean
bTrue;
for
(
int
i =
0
; i < s.length(); i++) {
bTrue =
false
;
//在数组s中找到当前字符串s的字母,如果数组t中相同位置字母不一致,则字符串不同构
for
(
int
j =
0
; j < len; j++) {
if
(charInS[j] ==
'0'
) {
break
;
}
else
if
(charInS[j] == s.charAt(i)) {
if
(charInT[j] != t.charAt(i)) {
return
false
;
}
bTrue =
true
;
}
}
if
(!bTrue) {
//在数组t中找到当前字符串t的字母,如果数组s中相同位置字母不一致,则字符串不同构
for
(
int
j =
0
; j < len; j++) {
if
(charInT[j] ==
'0'
) {
break
;
}
else
if
(charInT[j] == t.charAt(i)) {
return
false
;
}
}
//记录新的组合
for
(
int
k =
0
; k < len; k++) {
if
(charInS[k] ==
'0'
) {
charInS[k] = s.charAt(k);
charInT[k] = t.charAt(k);
break
;
}
}
}
}
return
true
;
}