同构字符串(哈希表)
题目要求
哈希表
作用: 快速判断一个元素是否在集合里
结构: 分为两部分,分别为“索引”,“元素”。例如数组就是一个简单的哈希表,对于数组a[i]来说,i为该哈希表的索引,而a[i]表示的值即为元素。对于一般的哈希表来说,其“索引”和“元素”的类型是随意的,比如两者可能是字符、数字等等
在该题中的应用:
在本题中,要求判断两s,t的字符串所表示的结构是否相同,简而言之就是说,s中的结构为:abb型,t中的结构如果是abb则返回true,反之则反。在该题中使用map<type,type>的储存容器
那么具体的原理可以看图:
map中的find()函数作用
map中的find函数作用为返回一个迭代器或常量迭代器,该迭代器或常量迭代器引用键在映射中的位置。如果键不存在于Map容器中,则它返回引用map.end()的迭代器或常量迭代器。
简单说,在该题中就是判断字符串s、t中的值是否在map中被定义过
代码
class Solution {
public:
bool isIsomorphic(string s, string t) {
unordered_map<char, char> map1;
unordered_map<char, char> map2;
for (int i = 0; i < s.size(); i++)
if (map1.find(s[i]) == map1.end()) { // map1保存s[i] 到 t[j]的映射
map1[s[i]] = t[i];
}
if (map2.find(t[i]) == map2.end()) { // map2保存t[j] 到 s[i]的映射
map2[t[i]] = s[i];
}
// 判断是否一一对应,即s、t的值是否可以用两map中的映射关系正确表示
if (map1[s[i]] != t[i] || map2[t[i]] != s[i]) {
return false;
}
}
return true;
}
};
小结
该题是看过题解做出来的,主要原因还是不熟悉哈希表的使用,下次应该练一练哈希碰撞的内容
修改
修改一:
利用数组也可以直接做,这样考虑,每个字符都有对应的ascll码,这个ascll码的值可以当作数组的下标。对于26个字母而言,最后一个ascll码的值为126,所以数组开到126大小就可以了。
class Solution {
public:
bool isIsomorphic(string s, string t) {
if (s.empty()) return true;
else
{
int arrs[126] = {};
int arrc[126] = {};
for (int i = 0; i < s.size(); i++) {
if (arrs[s[i]] == 0)
arrs[s[i]] = t[i];
if (arrc[t[i]] == 0)
arrc[t[i]] = s[i];
if (arrc[t[i]] != s[i]||arrs[s[i]] != t[i]) return false;
}
return true;
}
}
};
修改二:
利用map的count的函数,count函数的用法和find的用法相似,count是判断序列中有无该元素,如过有则返回1,负责返回0
class Solution {
public:
bool isIsomorphic(string s, string t) {
unordered_map<char, char> map1;
unordered_map<char, char> map2;
for (int i = 0; i < s.size(); i++)
if (map1.count(s[i]) == 0) { // map1保存s[i] 到 t[j]的映射
map1[s[i]] = t[i];
}
if (map2.count(t[i]) == 0) { // map2保存t[j] 到 s[i]的映射
map2[t[i]] = s[i];
}
// 判断是否一一对应,即s、t的值是否可以用两map中的映射关系正确表示
if (map1[s[i]] != t[i] || map2[t[i]] != s[i]) {
return false;
}
}
return true;
}
};
修改三:
s和t字符串中最多可能出现26*2即52个字母,所以可以直接开该大小的空间。然后在储存时,对每个字符取余52,就可以直接保存
class Solution {
public:
bool isIsomorphic(string s, string t) {
if (s.empty()) return true;
else
{
int arrs[52] = {};
int arrc[52] = {};
for (int i = 0; i < s.size(); i++) {
if (arrs[s[i]] == 0)
arrs[s[i]%52] = t[i]%52;
if (arrc[t[i]] == 0)
arrc[t[i]%52] = s[i]%52;
if (arrc[t[i]] != s[i]||arrs[s[i]] != t[i]) return false;
}
return true;
}
}
};