题目:
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.
比较典型的Backtracing,注意更新hashmap的时候不要犯错。
C++版:
class Solution {
public:
bool wordPatternMatch(string pattern, string str) {
unordered_map<char, string> d;
unordered_map<string, bool> used;
return match(pattern, str, d, used);
}
bool match(string pattern, string str, unordered_map<char, string> &d, unordered_map<string, bool> &used) {
if(pattern.length() == 0 && str.length() == 0)
return true;
if(pattern.length() == 0 || str.length() == 0)
return false;
if(pattern.length() == 1) {
if(d.find(pattern[0]) == d.end()) {
if(used.find(str) == used.end())
return true;
else
return false;
} else {
if(d[pattern[0]] == str)
return true;
else
return false;
}
}
if(d.find(pattern[0]) != d.end()) {
if(str.find(d[pattern[0]]) != 0)
return false;
else {
bool result = match(pattern.substr(1), str.substr(d[pattern[0]].length()), d, used);
if(result)
return true;
}
} else {
int length = str.length() - (pattern.length() - 1);
for(int i = 1; i <= length; i++) {
string cur = str.substr(0, i);
d.insert(pair<char, string>(pattern[0], cur));
used.insert(pair<string, bool>(cur, true));
bool result = match(pattern.substr(1), str.substr(cur.length()), d, used);
d.erase(pattern[0]);
used.erase(cur);
if(result)
return true;
}
}
return false;
}
};
Python版:
class Solution(object):
def wordPatternMatch(self, pattern, str):
"""
:type pattern: str
:type str: str
:rtype: bool
"""
d, used = {}, {}
return self.match(pattern, str, d, used)
def match(self, pattern, str, d, used):
if len(pattern) == 0 and len(str) == 0:
return True
elif len(pattern) == 0 or len(str) == 0:
return False
if len(pattern) == 1:
if pattern in d:
if d[pattern] == str:
return True
else:
return False
else:
if str in used and used[str]:
return False
else:
return True
if pattern[0] in d:
if str.find(d[pattern[0]]) != 0:
return False
else:
result = self.match(pattern[1:], str[len(d[pattern[0]]):], d, used)
if result:
return True
else:
length = len(str) - (len(pattern) - 1)
for i in range(length):
cur = str[:i+1]
if cur in used and used[cur]:
continue
used[cur] = True
d[pattern[0]] = cur
result = self.match(pattern[1:], str[len(cur):], d, used)
del d[pattern[0]]
if result:
return True
del used[cur]
return False