205. 同构字符串
此题是「290. 单词规律」的简化版,需要我们判断 s 和 t 每个位置上的字符是否都一一对应,即 s 的任意一个字符被 t 中唯一的字符对应,同时 t 的任意一个字符被 s 中唯一的字符对应。这也被称为「双射」的关系。
以示例 2为例,t 中的字符 a 和 r虽然有唯一的映射 o,但对于 s 中的字符 o 来说其存在两个映射 {a,r},故不满足条件。
因此,我们维护两张哈希表:
- 第一张哈希表 s2t 以 s 中字符为键,映射至 t 的字符为值,
- 第二张哈希表 t2s 以 t 中字符为键,映射至 s 的字符为值。
从左至右遍历两个字符串的字符,不断更新两张哈希表,看是否冲突(若s[i]已经存在hash中的key,则看它对应的value是否等于t[i],若不等于,则返回false)。
如果遍历结束没有出现冲突,则表明两个字符串是同构的,返回 true 即可。
class Solution {
public:
// 哈希表法
bool isIsomorphic(string s, string t) {
unordered_map<char, char> s2t; // key是s[i], value是t[i]
unordered_map<char, char> t2s; // key是t[i], value是s[i]
for (int i = 0; i < s.size(); ++i) {
auto pos = s2t.find(s[i]);
auto pos1 = t2s.find(t[i]);
if ((pos != s2t.end()) && (pos->second != t[i])) {
return false;
} else {
s2t[s[i]] = t[i];
}
if ((pos1 != t2s.end()) && (pos1->second != s[i])) {
return false;
} else {
t2s[t[i]] = s[i];
}
}
return true;
}
};
290. 单词规律
这题和上面一题类似,不同之处在于,这题需要多做一步单词提取。
class Solution {
public:
bool wordPattern(string pattern, string s) {
// 利用双指针,把word提取出来
s = s+" ";
vector<string> words;
int l = 0;
int r = 1;
while (l+r < s.size()) {
if (s[l+r] != ' ') {
r++;
} else {
string word = s.substr(l, r);
words.push_back(word);
l = l+r+1;
r = 1;
}
}
if (words.size() != pattern.size()) {
return false;
}
// Hash
unordered_map<char, string> hash;
unordered_map<string, char> hash2;
for (int i = 0; i < pattern.size(); ++i) {
auto pos = hash.find(pattern[i]);
auto pos2 = hash2.find(words[i]);
if (pos != hash.end() && pos->second != words[i]) {
return false;
} else {
hash[pattern[i]] = words[i];
}
if (pos2 != hash2.end() && pos2->second != pattern[i]) {
return false;
} else {
hash2[words[i]] = pattern[i];
}
}
return true;
}
};