题目:
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 substring in str
.
Examples:
- pattern =
"abab"
, str ="redblueredblue"
should return true. - pattern =
"aaaa"
, str ="asdasdasdasd"
should return true. - pattern =
"aabb"
, str ="xyzabcxzyabc"
should return false.
Notes:
You may assume both pattern
and str
contains only lowercase letters.
思路:
和上一道题目项目,由于没有空格可以分割,所以只能进行暴力搜索。我想到的第一种搜索策略是:首先统计pattern中的每个字符出现的次数,然后暴力搜索不同字符对应word长度的组合,大概意思就是找出满足sum(hash[p[i]] * num(p[i])) = str.length()的所有组合num(p[i]),其中hash[p[i]]表示p[i]在pattern中的出现次数,num(p[i])表示p[i]对应的word的长度。然后对于每一个组合,采用和上一题目相同的思路,去验证是否满足word pattern的匹配,一旦发现有一个组合满足,就返回true,否则返回false。
后来在网上看到一种采用深度优先策略直接搜索的代码,确实不太容易理解,不过还是贴出来供大家参考。(等到自己完全理解了再来这里补充思路,有对这个代码特别理解的大神,欢迎在评论中解惑)。
代码:
class Solution {
public:
bool wordPatternMatch(string pattern, string str) {
return DFS(pattern, 0, str, 1);
}
private:
bool DFS(string &p, int k, string &str, int len) {
int pLen = p.size(), sLen = str.size();
if(pLen == k && sLen == 0) {
return true;
}
if(pLen - k > sLen || pLen == k || sLen == 0 || len > sLen) {
return false;
}
if(DFS(p, k, str, len + 1)) {
return true;
}
string left = str.substr(0, len), right = str.substr(len);
int flag = hash1.count(p[k]);
if(hash1.count(p[k]) && hash1[p[k]] != left) {
return false;
}
if(hash2.count(left) && hash2[left] != p[k]) {
return false;
}
hash1[p[k]] = left, hash2[left] = p[k];
if(DFS(p, k + 1, right, 1)) {
return true;
}
if(hash1.count(p[k]) != flag) {
hash1.erase(p[k]), hash2.erase(left);
}
return false;
}
unordered_map<char, string> hash1;
unordered_map<string, char> hash2;
};