leetcode笔记:Word Pattern

一. 题目描述

Given a pattern and a string str, find if str follows the same pattern.

Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in str.

Examples:
pattern = "abba", str = "dog cat cat dog" should return true.
pattern = "abba", str = "dog cat cat fish" should return false.
pattern = "aaaa", str = "dog cat cat dog" should return false.
pattern = "abba", str = "dog dog dog dog" should return false.

Notes:
You may assume pattern contains only lowercase letters, and str contains lowercase letters separated by a single space.

二. 题目分析

题目的大意是,给出一组模式(pattern)和一个字符串(str),判断字符串是否与模式相匹配,并给出了几个例子。

题目提到,模式pattern仅由小写字母构成,而字符串str中每个单词均被单个空格字符隔开,且字符串中每个单词都由小写字母构成(这种设定可以少考虑很多边界条件);模式pattern和字符串str的前后都不包含多余的空格;且模式pattern中的每个字母必须匹配一个字符串str中长度至少为1的单词。

容易想到的是,使用Map来解决这个问题。

于是乎,定义一个map<char, string>,每遇到一个新的模式,以模式为key,将对应的单词存入map;遇到map里已有的模式,检查当前str的单词是否与map记载模式所对应的value值相同,只要出现不同,直接返回false

这种判断方法可以解决:pattern = "abba", str = "dog cat cat fish"这种情况。

但是,只使用一个map无法判断这种情况:pattern = "abba", str = "dog dog dog dog",一开始a作为一个新模式,<a, dog>被存入map,到了第二次迭代,b作为一个新模式,<b, dog>也被存入mapdog被分配到两个不同的模式,显然这是不对的。

为了解决这个问题,需要两个map。另一个map2<string, char>用于记载单词与模式的对应关系。

总的来说,map用于记载模式到单词的对应关系,但可能出现多个模式对应到同个单词的情形。

而map2用于记载单词到模式的对应关系,在判断中同时加入对两个map的判断,才可以分辨所有情况。

三. 示例代码

class Solution {
public:
    bool wordPattern(string pattern, string str) {
        unordered_map<char, string> map; // 作用是防止出现单词不同但模式相同的情况
        unordered_map<string, char> map2; // 作用是防止出现模式不同但单词同名的情况
        vector<string> vec; // 存放逐个单词
        // 以下操作分割str为多个单词
        for (int i = 0, j = 0; i < str.size(); ++i)
        {
            if (i == str.size() - 1)
            {
                string temp = str.substr(j, i - j + 1);
                vec.push_back(temp);
            }
            if (str[i] == ' ')
            {
                string temp = str.substr(j, i - j);
                vec.push_back(temp);
                j = i + 1;
            }
        }

        if (pattern.size() != vec.size()) return false;

        for (int i = 0; i < pattern.size(); ++i)
        {
            // 当前模式未出现,且对应的单词也未出现,才将键值对存入表
            if (map.find(pattern[i]) == map.end() && map2.find(vec[i]) == map2.end())
            {
                map.insert(make_pair(pattern[i], vec[i]));
                map2.insert(make_pair(vec[i], pattern[i]));
            }
            else if (map[pattern[i]] != vec[i]) 
                return false;
        }

        return true;
    }
};

四. 小结

思路简单的一道题,但实现起来还是要花点时间,而且需要注意一些细节问题。

你可能感兴趣的:(LeetCode,C++,算法,String,map)