题目:
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)由于是双射(bijection),所以我们不仅需要验证从pattern到str是否符合映射条件,还需要验证从str到pattern是否符合映射条件,只有两者都符合,才是合法的模式匹配。2)在分解str的过程中,采用istringstream可以非常方便地将str分解成以空格为分隔符的字符串数组。3)采用哈希表或者二叉搜索树都可以,哈希表增删改的时间复杂度低,但空间复杂度高,适合规模不大的数据,而二叉搜索树则刚好相反。
代码:
class Solution {
public:
bool wordPattern(string pattern, string str) {
vector<string> tokens;
istringstream iss(str);
do {
string sub;
iss >> sub;
if (sub != "") {
tokens.push_back(sub);
}
} while (iss);
if (pattern.length() != tokens.size()) {
return false;
}
std::map<char, string> patternMap; // check the map from pattern to str
std::map<char, string>::iterator it1;
for (int i = 0; i < pattern.length(); ++i) {
it1 = patternMap.find(pattern[i]);
if (it1 == patternMap.end()) {
patternMap.insert(pair<char, string>(pattern[i], tokens[i]));
}
else {
if (it1->second != tokens[i]) {
return false;
}
}
}
std::map<string, char> strMap; // check the map from str to pattern
std::map<string, char>::iterator it2;
for (int i = 0; i < tokens.size(); ++i) {
it2 = strMap.find(tokens[i]);
if (it2 == strMap.end()) {
strMap.insert(pair<string, char>(tokens[i], pattern[i]));
}
else {
if (it2->second != pattern[i]) {
return false;
}
}
}
return true;
}
};