You have a list of words and a pattern, and you want to know which words in words matches the pattern.
A word matches the pattern if there exists a permutation of letters pso that after replacing every letter x in the pattern with p(x), we get the desired word.
(Recall that a permutation of letters is a bijection from letters to letters: every letter maps to another letter, and no two letters map to the same letter.)
Return a list of the words in words that match the given pattern.
You may return the answer in any order.
Example 1:
Input: words = ["abc","deq","mee","aqq","dkd","ccc"], pattern = "abb"
Output: ["mee","aqq"]
Explanation: "mee" matches the pattern because there is a permutation {a -> m, b -> e, ...}.
"ccc" does not match the pattern because {a -> c, b -> c, ...} is not a permutation,
since a and b map to the same letter.
Note:
1 <= words.length <= 501 <= pattern.length = words[i].length <= 20
给一个单词列表和一个模式字符串,从单词数组中找到和字符串模式匹配的单词。与题目205. Isomorphic Strings 类似
解法:循环单词列表的每一个单词,调用子函数判断是否符合要求。子函数里用哈希表记录每一个字符出现的位置,如果对应的字符出现的位置不一样,就返回False,到最后都一样就返回True。也可以只记录最后一个字符出现的位置,因为之前出现的位置已经比较过了。
Java:
public List<String> findAndReplacePattern(String[] words, String pattern) {
int[] p = F(pattern);
List<String> res = new ArrayList<String>();
for (String w : words)
if (Arrays.equals(F(w), p)) res.add(w);
return res;
}
public int[] F(String w) {
HashMap<Character, Integer> m = new HashMap<>();
int n = w.length();
int[] res = new int[n];
for (int i = 0; i < n; i++) {
m.putIfAbsent(w.charAt(i), m.size());
res[i] = m.get(w.charAt(i));
}
return res;
}
Python:
# Time: O(n * l)
# Space: O(1)
import itertools
class Solution(object):
def findAndReplacePattern(self, words, pattern):
"""
:type words: List[str]
:type pattern: str
:rtype: List[str]
"""
def match(word):
lookup = {}
for x, y in itertools.izip(pattern, word):
if lookup.setdefault(x, y) != y:
return False
return len(set(lookup.values())) == len(lookup.values())
return filter(match, words)
Python:
def findAndReplacePattern(self, words, p):
def F(w):
m = {}
for c in w: m[c] = m.get(c, len(m))
return "".join(chr(m[c] + 97) for c in w)
return [w for w in words if F(w) == F(p)]
Python: Similar to isomorphic string, check the length of the sets and the length of the set when the characters are zipped together.
b = pattern
def is_iso(a):
return len(a) == len(b) and len(set(a)) == len(set(b)) == len(set(zip(a, b)))
return filter(is_iso, words)
C++:
vector<string> findAndReplacePattern(vector<string> words, string p) {
vector<string> res;
for (string w : words) if (F(w) == F(p)) res.push_back(w);
return res;
}
string F(string w) {
unordered_map<char, int> m;
for (char c : w) if (!m.count(c)) m[c] = m.size();
for (int i = 0; i < w.length(); ++i) w[i] = 'a' + m[w[i]];
return w;
}
C++:
// Time: O(n * l)
// Space: O(1)
class Solution {
public:
vector<string> findAndReplacePattern(vector<string>& words, string pattern) {
vector<string> result;
for (const auto& word: words) {
if (match(word, pattern)) {
result.emplace_back(word);
}
}
return result;
}
private:
bool match(const string& word, const string& pattern) {
unordered_map<char, char> lookup;
unordered_set<char> char_set;
for (int i = 0; i < word.length(); ++i) {
const auto& c = word[i], &p = pattern[i];
if (!lookup.count(c)) {
if (char_set.count(p)) {
return false;
}
char_set.emplace(p);
lookup[c] = p;
}
if (lookup[c] != p) {
return false;
}
}
return true;
}
};
类似题目:
[LeetCode] 205. Isomorphic Strings 同构字符串