力扣-单词规律

核心解题思路:双哈希表双向校验

两个哈希表的分工

  1. ch2word(字符→单词)

    • key:pattern 里的单个字母
    • value:该字母对应的单词
    • 作用:校验「一个字母只能对应一个单词」
  2. word2ch(单词→字符)

    • key:s 里的单个单词
    • value:该单词对应的字母
    • 作用:校验「一个单词只能对应一个字母」

核心逻辑

遍历每一组「字母 + 对应单词」,每一步做两次冲突检查:

  1. 如果这个字母已经存过映射,但对应的单词不是当前单词 → 冲突,返回 false
  2. 如果这个单词已经存过映射,但对应的字母不是当前字母 → 冲突,返回 false 两次检查都通过,就把这组对应关系存入两个哈希表,继续下一组。

完整解题步骤

步骤 1:拆分单词(C++ 必手写)

C++ 没有内置的字符串分割函数,需要手动把 s 按空格切割成单词数组。

  • 遍历字符串 s,遇到空格就截断,把每个单词存入 vector<string> words
  • 快速预判 :如果 words.size() != pattern.size(),数量都对不上,直接返回 false

步骤 2:初始化两个哈希表

复制代码
unordered_map<char, string> ch2word;  // 字母 → 单词
unordered_map<string, char> word2ch;  // 单词 → 字母

步骤 3:逐位遍历,双向校验

复制代码
遍历下标 i 从 0 到 pattern末尾:
    取出当前字母 c = pattern[i]
    取出当前单词 w = words[i]
    
    检查1:c 已经在 ch2word 里,但 ch2word[c] != w → 冲突,返回 false
    检查2:w 已经在 word2ch 里,但 word2ch[w] != c → 冲突,返回 false
    
    都没问题:更新两个哈希表,存入 c ↔ w 的映射

步骤 4:遍历完成,无冲突 → 返回 true

cpp 复制代码
class Solution {
public:
    bool wordPattern(string pattern, string s) {
        //数组用来存拆分好的单词
        vector<string> words;
        //拆分

        int n = s.size();
        int i = 0;
        while(i<n){
            while(i<n&&s[i]==' '){

                i++;
            }


            if(i>=n) break;

            //找到当前单词的结尾
            int j = i;
            while(j<n && s[j]!=' '){
                j++;
            }

            words.push_back(s.substr(i,j-i));
            i = j;
        }

        if(pattern.size()!= words.size()){
            return false;
        }

        unordered_map<char,string> ch2word;
        unordered_map<string,char> word2ch;

        for(int k = 0;k<pattern.size();k++){
            char c = pattern[k];
            string w  = words[k];

            if(ch2word.count(c)&&ch2word[c]!=w){
                return false;
            }

            if(word2ch.count(w)&&word2ch[w]!=c){
                return false;
            }

            //更新双向映射
            ch2word[c] = w;
            word2ch[w] = c;
        }

        return true;
        
        
    }
};