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.
Example 1:
Input: pattern = "abba", str = "dog cat cat dog" Output: true
Example 2:
Input:pattern = "abba", str = "dog cat cat fish" Output: false
Example 3:
Input: pattern = "aaaa", str = "dog cat cat dog" Output: false
Example 4:
Input: pattern = "abba", str = "dog dog dog dog" Output: false
题目大意:
给定两个字符串pattern和str,根据pattern给定的规律,判断str是否也遵循该规律。
理 解:
看到题目示例会误解为只需判断pattern是对此还是全等,这是错误的。
其实,这个题目和之前的一个字符串中字符替换的题目类似。只是,这里是单词替换字符。
用map保存字符和单词的映射关系。用set保存已被映射的单词以防不同字符映射到同一单词。
先将str中的单词分割存放在vector中,若vector的大小和pattern的长度不等,则返回false。
遍历pattern,当前字符pattern[i] 若未出现,则判断对应的单词是否出现,已出现则 false;否则添加该映射至map中。
若当前字符pattern[i] 已出现,判断当前对应单词与map中映射的单词是否一致,一致继续遍历,否则,返回false。
代 码 C++:
class Solution {
public:
bool wordPattern(string pattern, string str) {
vector<string> splitWords; // 分割str为单词
int startPos=0,blankPos; // 记录单词的起始位置、空格的位置
string word; // 存放单词
map<char, string> m; // 存放两字符串间的映射关系
map<char, string>::iterator it;
set<string> m_set; // 防止多个字符映射至同一单词
int i = 0; // 遍历
while ((blankPos = str.find(' ', startPos))!=str.npos) {
word = str.substr(startPos, blankPos-startPos); // 起始位置和长度
splitWords.push_back(word);
startPos = blankPos + 1;
}
// 处理最后一个单词
if (startPos < str.length()) {
word = str.substr(startPos);
splitWords.push_back(word);
}
if (pattern.length() != splitWords.size())
return false;
while (pattern[i] != '\0') {
it = m.find(pattern[i]);
if (it == m.end()) {
if (m_set.find(splitWords[i]) == m_set.end()) {
m_set.insert(splitWords[i]);
}
else {
return false;
}
m.insert(pair<char, string>(pattern[i], splitWords[i]));
i++;
}
else {
if (strcmp((it->second).c_str(), splitWords[i].c_str()) == 0)
i++;
else
return false;
}
}
return true;
}
};
运行结果:
执行用时 :4 ms, 在所有C++提交中击败了94.12%的用户
内存消耗 :8.9 MB, 在所有C++提交中击败了5.10%的用户
来源:https://www.cnblogs.com/lpomeloz/p/11026962.html