在给定单词列表 wordlist
的情况下,我们希望实现一个拼写检查器,将查询单词转换为正确的单词。
对于给定的查询单词 query
,拼写检查器将会处理两类拼写错误:
wordlist = ["yellow"]
, query = "YellOw"
: correct = "yellow"
wordlist = ["Yellow"]
, query = "yellow"
: correct = "Yellow"
wordlist = ["yellow"]
, query = "yellow"
: correct = "yellow"
a
、e
、i
、o
、u
)分别替换为任何元音后,能与单词列表中的单词匹配(不区分大小写),则返回的正确单词与单词列表中的匹配项大小写相同。
wordlist = ["YellOw"]
, query = "yollow"
: correct = "YellOw"
wordlist = ["YellOw"]
, query = "yeellow"
: correct = ""
(无匹配项)wordlist = ["YellOw"]
, query = "yllw"
: correct = ""
(无匹配项)此外,拼写检查器还按照以下优先级规则操作:
给出一些查询 queries
,返回一个单词答案列表 answer
,其中 answer[i]
是由查询 query = queries[i]
得到的正确单词。
示例:
输入:wordlist = ["KiTe","kite","hare","Hare"], queries = ["kite","Kite","KiTe","Hare","HARE","Hear","hear","keti","keet","keto"]
输出:["kite","KiTe","KiTe","Hare","hare","","","KiTe","","KiTe"]
提示:
1 <= wordlist.length <= 5000
1 <= queries.length <= 5000
1 <= wordlist[i].length <= 7
1 <= queries[i].length <= 7
wordlist
和 queries
中的所有字符串仅由英文字母组成。解题思路
比赛的时候这道题让我很难受,首先题目很长,然后解起来又很繁琐,索性题目不难。这其实是一个映射问题,我们只要找到对应的映射关系就很好解决这个问题。主要分成三大类
完全匹配
大小写匹配
元音匹配
对于第一种情况,如果输入单词是小写的话,我们建立的关系是s+'_' → s
。例如
kite_ → kite
如果输入单词包含大写的话,我们建立s → s
的映射,例如
Kite → Kite
对于第二种情况,如果输入单词是小写的话,我们建立的关系是s → s
。例如
kite → kite
如果输入单词中有大写的话,我们建立的关系是s.lower() → s
。例如
kite → Kite
对于第三种情况,对于包含元音字母的单词建立映射,例如kite
,Kite
k_t_ → kite Kite
接着就是编写代码
class Solution:
def spellchecker(self, wordlist, queries):
"""
:type wordlist: List[str]
:type queries: List[str]
:rtype: List[str]
"""
words_dict = {}
for s in wordlist[::-1]:
s_low = s.lower()
if s_low == s:
words_dict[s+'_'] = s
else:
words_dict[s] = s
words_dict[s_low] = s
k = s_low
for c in k:
if c in 'aeiou':
k = k.replace(c, '_')
if k != s_low:
words_dict[k] = s
res = list()
for s in queries:
s_low = s.lower()
st = s + '_'
if st in words_dict:
res.append(words_dict[st])
elif s in words_dict:
res.append(words_dict[s])
elif s_low in words_dict:
res.append(words_dict[s_low])
else:
for c in s_low:
if c in 'aeiou':
s_low = s_low.replace(c, '_')
if s_low in words_dict:
res.append(words_dict[s_low])
else:
res.append("")
return res
注意这里的wordlist reverse
,因为我们希望匹配到的是第一个符合条件的单词,所以通过从前向后覆盖即可。
一个更好的解法就是通过三个字典分别存放匹配结果。这样我们就不用通过'_'
的方式处理大小匹配
和完全匹配
相同字段。
import re
class Solution:
def spellchecker(self, wordlist, queries):
"""
:type wordlist: List[str]
:type queries: List[str]
:rtype: List[str]
"""
words = {w: w for w in wordlist}
cap = {w.lower(): w for w in wordlist[::-1]}
vowel = {re.sub("[aeiou]", '#', w.lower()): w for w in wordlist[::-1]}
return [words.get(w) or cap.get(w.lower()) or vowel.get(re.sub("[aeiou]", '#', w.lower()), "") for w in queries]
reference:
https://leetcode.com/problems/vowel-spellchecker/discuss/211189/JavaC%2B%2BPython-Two-HashMap
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!