Question:
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.
Solution:
建立两个map,相当于建立一个双向映射,对每一个pattern建立到一个单词的映射,同时建立一个反映射,然后判断后续的已出现的pattern是否对应正确的单词就好。注意pattern比单词多或单词比pattern多的情况就好。
AC后看了一眼别人的代码,思路是类似的,不过不用建立第二个映射,使用set记录已出现的单词就好,还有获得单词直接使用索引,不用每次都把string的一部分去掉,节省时间。
时间复杂度:O(n)
空间复杂度:O(n)
class Solution {
public:
bool wordPattern(string pattern, string str) {
map<char, string> m1;
map<string, char> m2;
for (int i = 0; i < pattern.size(); i++) {
string tmp = getNext(str);
if (tmp == "") return false;
if (m1.find(pattern[i]) == m1.end()) {
if (m2.find(tmp) == m2.end()) {
m1[pattern[i]] = tmp;
m2[tmp] = pattern[i];
} else {
cout << "1 " << tmp;
return false;
}
} else if (m1[pattern[i]] != tmp) {
return false;
}
}
if (str.empty())
return true;
return false;
}
string getNext(string & str) {
string ret;
for (int i = 0; i < str.size(); i++) {
if (str[i] == ' ') {
str = str.substr(i+1);
return ret;
}
ret += str[i];
}
ret = str;
str = "";
return ret;
}
};