步骤 1:理解题意
"模式匹配" = 单词与 pattern 长度相同,且字符间双射 (一一对应,无重复映射)。
即:
- 同一字母在 pattern 中多次出现,必须映射到单词的同一字母;
- 不同字母不能映射到同一字母(双向唯一)。
步骤 2:写出暴力/朴素解法
对每单词,建两个 Map<Character, Character> 分别记录 pattern→word 与 word→pattern 的映射,中途冲突即不匹配。
时间 O(N·L),N 为 words 长度,L 为单词长度。
步骤 3:寻找冗余与优化点
- 只需一次遍历即可同时检查双向映射,无需两个 map。
- 用长度 26 的数组代替
HashMap,更快。 - 提前长度不等直接跳过。
步骤 4:给出最优"快刷"版本
java
public List<String> findAndReplacePattern(String[] words, String pattern) {
List<String> ans = new ArrayList<>();
char[] p = pattern.toCharArray();
for (String w : words) {
if (w.length() != p.length) continue;
char[] s = w.toCharArray();
char[] map1 = new char[26], map2 = new char[26];
boolean ok = true;
for (int i = 0; i < s.length; i++) {
char a = p[i], b = s[i];
// 建立双向映射
if (map1[a - 'a'] == 0) map1[a - 'a'] = b;
if (map2[b - 'a'] == 0) map2[b - 'a'] = a;
if (map1[a - 'a'] != b || map2[b - 'a'] != a) {
ok = false; break;
}
}
if (ok) ans.add(w);
}
return ans;
}
- 时间:O(N·L)
- 空间:O(1)(固定 52 字节数组)
- 可直接 copy 通过 LintCode 1592。