题目描述
给你两个字符串数组 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]
都只包含小写英文字母。
解法
方法一:暴力枚举
我们直接遍历数组 $\textit{queries}$ 中的每个单词 $s$,再遍历数组 $\textit{dictionary}$ 中的每个单词 $t$,如果存在一个单词 $t$ 与 $s$ 的编辑距离小于 $3$,则将 $s$ 加入答案数组中,然后退出内层循环的遍历。如果不存在这样的单词 $t$,则继续遍历下一个单词 $s$。
时间复杂度 $O(m \times n \times l)$,其中 $m$ 和 $n$ 分别是数组 $\textit{queries}$ 和 $\textit{dictionary}$ 的长度,而 $l$ 是单词的长度。
| class Solution:
def twoEditWords(self, queries: List[str], dictionary: List[str]) -> List[str]:
ans = []
for s in queries:
for t in dictionary:
if sum(a != b for a, b in zip(s, t)) < 3:
ans.append(s)
break
return ans
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | class Solution {
public List<String> twoEditWords(String[] queries, String[] dictionary) {
List<String> ans = new ArrayList<>();
int n = queries[0].length();
for (var s : queries) {
for (var t : dictionary) {
int cnt = 0;
for (int i = 0; i < n; ++i) {
if (s.charAt(i) != t.charAt(i)) {
++cnt;
}
}
if (cnt < 3) {
ans.add(s);
break;
}
}
}
return ans;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | class Solution {
public:
vector<string> twoEditWords(vector<string>& queries, vector<string>& dictionary) {
vector<string> ans;
for (auto& s : queries) {
for (auto& t : dictionary) {
int cnt = 0;
for (int i = 0; i < s.size(); ++i) {
cnt += s[i] != t[i];
}
if (cnt < 3) {
ans.emplace_back(s);
break;
}
}
}
return ans;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | func twoEditWords(queries []string, dictionary []string) (ans []string) {
for _, s := range queries {
for _, t := range dictionary {
cnt := 0
for i := range s {
if s[i] != t[i] {
cnt++
}
}
if cnt < 3 {
ans = append(ans, s)
break
}
}
}
return
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | function twoEditWords(queries: string[], dictionary: string[]): string[] {
const n = queries[0].length;
return queries.filter(s => {
for (const t of dictionary) {
let diff = 0;
for (let i = 0; i < n; ++i) {
if (s[i] !== t[i]) {
++diff;
}
}
if (diff < 3) {
return true;
}
}
return false;
});
}
|
1
2
3
4
5
6
7
8
9
10
11
12 | impl Solution {
pub fn two_edit_words(queries: Vec<String>, dictionary: Vec<String>) -> Vec<String> {
queries
.into_iter()
.filter(|s| {
dictionary
.iter()
.any(|t| s.chars().zip(t.chars()).filter(|&(a, b)| a != b).count() < 3)
})
.collect()
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | public class Solution {
public IList<string> TwoEditWords(string[] queries, string[] dictionary) {
var ans = new List<string>();
foreach (var s in queries) {
foreach (var t in dictionary) {
int cnt = 0;
for (int i = 0; i < s.Length; i++) {
if (s[i] != t[i]) {
cnt++;
}
}
if (cnt < 3) {
ans.Add(s);
break;
}
}
}
return ans;
}
}
|