每日一道leetcode(2026.04.22):距离字典两次编辑以内的单词
- [1. 题目](#1. 题目)
- [2. 分析](#2. 分析)
- [3. 代码实现](#3. 代码实现)
1. 题目
给你两个字符串数组 queries 和 dictionary 。数组中所有单词都只包含小写英文字母,且长度都相同。
一次 编辑 中,你可以从 queries 中选择一个单词,将任意一个字母修改成任何其他字母。从 queries 中找到所有满足以下条件的字符串:不超过 两次编辑内,字符串与 dictionary 中某个字符串相同。
请你返回 queries 中的单词列表,这些单词距离 dictionary 中的单词 编辑次数 不超过 两次 。单词返回的顺序需要与 queries 中原本顺序相同。
示例 1:
输入:queries = ["word","note","ants","wood"], dictionary = ["wood","joke","moat"]
输出:["word","note","wood"]
解释:
- 将 "word" 中的 'r' 换成 'o' ,得到 dictionary 中的单词 "wood" 。
- 将 "note" 中的 'n' 换成 'j' 且将 't' 换成 'k' ,得到 "joke" 。
- "ants" 需要超过 2 次编辑才能得到 dictionary 中的单词。
- "wood" 不需要修改(0 次编辑),就得到 dictionary 中相同的单词。 所以我们返回 ["word","note","wood"] 。
示例 2:
输入:queries = ["yes"], dictionary = ["not"]
输出:[]
解释: "yes" 需要超过 2 次编辑才能得到 "not" 。 所以我们返回空数组。
提示:
1 <= queries.length, dictionary.length <= 100
n == queries[i].length == dictionary[j].length
1 <= n <= 100
所有 queries[i] 和 dictionary[j] 都只包含小写英文字母。
2. 分析
这道题其实就是将queries数组中的字符串,允许修改其中两个字符的情况下,判断是否在dictionary中找到相同的字符串。我看官方的题解是有暴力解法的,执行了一下也不会超时,所以简单的直接遍历queries中的每个字符串,与dictionary中字符串的每个字符比较,差异小于等于2则说明可以返回。
我担心的是匹配的数据范围比较大,在循环的数据量那儿有超时等着我,所以想做一层数据筛选。具体做法是将dictionary中的所有的字符串的每个字符对应的数值加起来,那么在允许修改两个字符的情况下,一定是数值和差异在2倍的'z'-'a'范围内才有可能匹配。最终效果也确实比纯暴力解法要高效一丢丢。
3. 代码实现
java
Map<Integer, List<String>> mappingMap = new HashMap<>();
for (String str : dictionary) {
int val = mapping(str);
if (!mappingMap.containsKey(val)) {
mappingMap.put(val, new ArrayList<>());
}
mappingMap.get(val).add(str);
}
List<String> res = new ArrayList<>();
int offset = 2 * ('z' - 'a');
for (String str : queries) {
int val = mapping(str);
boolean matched = false;
for (int i = Math.max(0, val - offset); i < val + offset; i++) {
if (matched) {
break;
}
if (!mappingMap.containsKey(i)) {
continue;
}
List<String> list = mappingMap.get(i);
char[] queryCharArray = str.toCharArray();
for (String s : list) {
char[] targetCharArray = s.toCharArray();
int count = 0;
for (int j = 0; j < queryCharArray.length; j++) {
if (queryCharArray[j] != targetCharArray[j]) {
count++;
if (count > 2) {
break;
}
}
}
if (count <= 2) {
res.add(str);
matched = true;
break;
}
}
}
}
return res;
}
public static int mapping(String str) {
char[] charArray = str.toCharArray();
int val = 0;
for (char c : charArray) {
val += c;
}
return val;
}
