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.
解法1:遍历pattern,保存好当前的模式,同时遍历str,也保存下str的模式,二者匹配。
class Solution { public: bool wordPattern(string pattern, string str) { int ps = pattern.size(), ss = str.size(); vector< pair<char, int> > vc; vector< pair<string, int> > vs; int i = 0, j = 0, k = 0; for(; i < ps; ++i) { vector< pair<char, int> >::iterator iter1 = keyFind(vc.begin(), vc.end(), pattern[i]); if(iter1 == vc.end()) vc.push_back(make_pair(pattern[i], 1)); else iter1->second += 1;
while(j < ss && str[j] == ' ') ++j; k = j; while(j < ss && str[j] != ' ') ++j; if(k == j) return false; string s(str.begin() + k, str.begin() + j); vector< pair<string, int> >::iterator iter2 = keyFind(vs.begin(), vs.end(), s); if(iter2 == vs.end()) vs.push_back(make_pair(s, 1)); else iter2->second += 1; if(!sameVec(vc, vs)) return false; } return j == ss ? true : false; } private: bool sameVec(const vector< pair<char, int> >& vc, const vector< pair<string, int> >& vs) { int vcs = vc.size(), vss = vs.size(); if(vcs != vss) return false; for(int i = 0; i < vcs; ++i) if(vc[i].second != vs[i].second) return false; return true; } template<typename T> const typename vector< pair<T, int> >::iterator keyFind(const typename vector< pair<T, int> >::iterator beg, const typename vector< pair<T, int> >::iterator end, const T& patt) { typename vector< pair<T, int> >::iterator iter = beg; while(iter != end && iter->first != patt) ++iter; return iter; } };
解法2:使用Hash Map。实际上这题是一个一一映射的问题。
class Solution { public: bool wordPattern(string pattern, string str) { int ps = pattern.size(), ss = str.size(); int i = 0, j = 0, k = 0, cnt = 0; vector<string> cts(256, ""); //pattern中的字符映射到str中的单词 map<string, char> stc; //str中的单词映射到pattern中的字符 vector<int> flag(256, 0); //pattern中的字符是否已有了在str中的映射 for (; i < ps; ++i) { while (j < ss && str[j] == ' ') ++j; k = j; while (j < ss && str[j] != ' ') ++j; string word(str.begin() + k, str.begin() + j); ++cnt; if (flag[pattern[i]] == 0) { if (stc.find(word) == stc.end()) { cts[pattern[i]] = word; flag[pattern[i]] = 1; stc[word] = pattern[i]; } else return false; //str中相同的单词映射到了pattern中不同的字符 } else if (word != cts[pattern[i]]) return false; //pattern中的相同的字符映射到了str中两个不同的单词 if (j == ss) break; } if (cnt != ps || j != ss) return false; //str中单词数目和pattern中字符数目不一致 else return true; } };