哈希表——解205. 同构字符串及290. 单词规律
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; } };