Leetcode 966:元音拼写检查器(最详细的解法!!!)

在给定单词列表 wordlist 的情况下,我们希望实现一个拼写检查器,将查询单词转换为正确的单词。

对于给定的查询单词 query,拼写检查器将会处理两类拼写错误:

  • 大小写:如果查询匹配单词列表中的某个单词(不区分大小写),则返回的正确单词与单词列表中的大小写相同。
    • 例如:wordlist = ["yellow"], query = "YellOw": correct = "yellow"
    • 例如:wordlist = ["Yellow"], query = "yellow": correct = "Yellow"
    • 例如:wordlist = ["yellow"], query = "yellow": correct = "yellow"
  • 元音错误:如果在将查询单词中的元音(aeiou)分别替换为任何元音后,能与单词列表中的单词匹配(不区分大小写),则返回的正确单词与单词列表中的匹配项大小写相同。
    • 例如: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. 1 <= wordlist.length <= 5000
  2. 1 <= queries.length <= 5000
  3. 1 <= wordlist[i].length <= 7
  4. 1 <= queries[i].length <= 7
  5. wordlistqueries 中的所有字符串仅由英文字母组成。

解题思路

比赛的时候这道题让我很难受,首先题目很长,然后解起来又很繁琐,索性题目不难。这其实是一个映射问题,我们只要找到对应的映射关系就很好解决这个问题。主要分成三大类

  • 完全匹配
  • 大小写匹配
  • 元音匹配

对于第一种情况,如果输入单词是小写的话,我们建立的关系是s+'_' → s。例如

kite_ → kite

如果输入单词包含大写的话,我们建立s → s的映射,例如

Kite → Kite

对于第二种情况,如果输入单词是小写的话,我们建立的关系是s → s。例如

kite → kite

如果输入单词中有大写的话,我们建立的关系是s.lower() → s。例如

kite → Kite

对于第三种情况,对于包含元音字母的单词建立映射,例如kiteKite

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

如有问题,希望大家指出!!!

你可能感兴趣的:(Problems,leetcode解题指南)