LeetCode 每日一题 966. 元音拼写检查器
966. 元音拼写检查器
在给定单词列表 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] 得到的正确单词。
示例 1:
输入:wordlist = [“KiTe”,“kite”,“hare”,“Hare”], queries = [“kite”,“Kite”,“KiTe”,“Hare”,“HARE”,“Hear”,“hear”,“keti”,“keet”,“keto”]
输出:[“kite”,“KiTe”,“KiTe”,“Hare”,“hare”,“”,“”,“KiTe”,“”,“KiTe”]
示例 2:
输入:wordlist = [“yellow”], queries = [“YellOw”]
输出:[“yellow”]
题解
根据题意,我们需要对每一个查询进行三次判断
- 在 worldlist 里是否有完全相同字符串
- 如果不区分大小写的话,worldlist里是否有相同的字符串
- 将所有元音字母忽略掉同时不区分大小写,worldlist里是否有相同的字符串
我们试着做一下上述步骤
示例一中的 “keto” ,在 worldlist 中没有完全一样的,不满足第一条
然后我们不区分大小写,将 “keet” 和 worldlist 中的所有字符串都变为小写,仍旧没有相同的,不满足第二条
接着我们忽略元音同时不区分大小写,将 “keto” 和 “worldlist” 中所有的元音都变为 ‘a’ ,全变为小写,接着在 worldlist 中寻找是否有相同的,第一个 “KiTe” 变为 “kata” 和 “keto” 变为的 “kata” 相同,满足第三条
上述过程中,不难注意到,如果我们直接去遍历 query ,那么我们每一次查询都需要反复遍历 worldlist 会导致超时
- 关键思路:用哈希表存入字符串,直接访问从而避免遍历
对于一个确定的 worldlist ,其在不同条件下能够匹配到的字符串是有限的
在上述过程中,我们每次都要处理 worldlist 中的全部元素然后遍历
那么我们不妨直接处理三个条件下的 worldlist 将其用哈希表存起来
这样接下来我们对于每一个 query 判断 worldlist 中是否有相同的时候,直接去访问哈希表即可,省去了遍历的时间
所以我们创建三个哈希表 origin daxiao huanyuan,分别存储三个条件下 worldlist 中能够满足的字符串
origin 代表条件一,完全相同,什么都不用处理直接存放到哈西表里
daxiao 代表条件二,将 worldlist 中字符串变为小写存进去
huanyuan 代表条件三,全小写的同时将所有元音字母变成 ‘a’
哈希表里的值存的都是 worldlist 中的原本的字符串,也就是返回的数组里需要的字符串
还有一个问题,在对于多个字符串都能匹配的情况下,题目要求第一个匹配的,也就是最左边的
转换到哈希表就是:对于同一个键,我们需要存入的值得是最左边的
所以我们在向哈希表里存值的时候需要从右向左遍历 worldlist 这样同一个键左边的值会覆盖右边的,从而满足题意
代码如下↓
class Solution {
public:vector<string> spellchecker(vector<string>& wordlist, vector<string>& queries) {vector<string> res;unordered_map<string,string> origin;unordered_map<string,string> daxiao;unordered_map<string,string> huanyuan;int k=queries.size();int l=wordlist.size();for(int i=l-1;i>-1;i--){string s=wordlist[i];origin[wordlist[i]]=s;int n=s.size();string lower=s;for(int j=0;j<n;j++){lower[j]=tolower(lower[j]);}daxiao[lower]=s;string huan=lower;for(int j=0;j<n;j++){if(huan[j]=='a' || huan[j]=='e' || huan[j]=='i' || huan[j]=='o' || huan[j]=='u'){huan[j]='a';}}huanyuan[huan]=s;}for(int i=0;i<k;i++){string q=queries[i];if(origin.count(q)){res.push_back(q);}else{int m=q.size();for(int j=0;j<m;j++){q[j]=tolower(q[j]);}if(daxiao.count(q)){res.push_back(daxiao[q]);}else{for(int j=0;j<m;j++){if(q[j]=='a' || q[j]=='e' || q[j]=='i' || q[j]=='o' || q[j]=='u'){q[j]='a';}}if(huanyuan.count(q)){res.push_back(huanyuan[q]);}else{res.push_back("");}}}}return res;}
};