哈希表——解205. 同构字符串及290. 单词规律

发布时间 2023-08-20 18:03:59作者: blogzzt

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;
    }
};