Given a wordlist, we want to implement a spellchecker that converts a query word into a correct word.

For a given query word, the spell checker handles two categories of spelling mistakes:

  • Capitalization: If the query matches a word in the wordlist (case-insensitive), then the query word is returned with the same case as the case in the wordlist.

    • Example: wordlist = ["yellow"], query = "YellOw": correct = "yellow"
    • Example: wordlist = ["Yellow"], query = "yellow": correct = "Yellow"
    • Example: wordlist = ["yellow"], query = "yellow": correct = "yellow"
  • Vowel Errors: If after replacing the vowels ('a', 'e', 'i', 'o', 'u') of the query word with any vowel individually, it matches a word in the wordlist (case-insensitive), then the query word is returned with the same case as the match in the wordlist.
    • Example: wordlist = ["YellOw"], query = "yollow": correct = "YellOw"
    • Example: wordlist = ["YellOw"], query = "yeellow": correct = "" (no match)
    • Example: wordlist = ["YellOw"], query = "yllw": correct = "" (no match)

In addition, the spell checker operates under the following precedence rules:

  • When the query exactly matches a word in the wordlist (case-sensitive), you should return the same word back.
  • When the query matches a word up to capitlization, you should return the first such match in the wordlist.
  • When the query matches a word up to vowel errors, you should return the first such match in the wordlist.
  • If the query has no matches in the wordlist, you should return the empty string.

Given some queries, return a list of words answer, where answer[i] is the correct word for query = queries[i].

Example 1:

Input: wordlist = ["KiTe","kite","hare","Hare"], queries = ["kite","Kite","KiTe","Hare","HARE","Hear","hear","keti","keet","keto"]
Output: ["kite","KiTe","KiTe","Hare","hare","","","KiTe","","KiTe"]

Note:

  • 1 <= wordlist.length <= 5000
  • 1 <= queries.length <= 5000
  • 1 <= wordlist[i].length <= 7
  • 1 <= queries[i].length <= 7
  • All strings in wordlist and queries consist only of english letters.

踩坑踩了一个下午,掉到坑里出不来了。

Runtime: 96 ms, faster than 100.00% of C++ online submissions for Vowel Spellchecker.

第一种是我的做法 修改了TrieNode的结构,让它带了一个case_sensitive的标志位。如果带上大小写搜索,

每次需要判断字符的大小写,这样得到的是第一种准确的搜索。如果不敏感,就全部放在小写的这个节点里。

为了满足题意,大小写不敏感的可能有多种,那么Trie节点带一个数组比较合适。

注意:

1. 本来的字典可能有重复,我去。。。

2. 需要返回最小的index,那就把所有的求出来以后再求最小的index。

写了一个下午。

class TrieNode{
public:
string word;
vector<string> wordlist;
TrieNode* lowercase[];
TrieNode* uppercase[];
TrieNode(){
for(int i=; i<; i++) lowercase[i] = nullptr;
for(int i=; i<; i++) uppercase[i] = nullptr;
}
}; class Trie{
public:
TrieNode* root;
Trie(const vector<string>& wordlist, bool case_sensitive = true){
root = new TrieNode();
BuildTrie(wordlist, case_sensitive);
}
void BuildTrie(const vector<string>& wordlist, bool case_sensitive = true){ for(int i=; i<wordlist.size(); i++){
TrieNode* tmp = root;
for(int j=; j<wordlist[i].size(); j++){
char tmpchar = wordlist[i][j];
int idx = ;
if(!case_sensitive){
if(tmpchar >= 'A' && tmpchar <= 'Z'){
idx = tmpchar - 'A';
}else idx = tmpchar - 'a';
if(!tmp->lowercase[idx]) tmp->lowercase[idx] = new TrieNode();
tmp = tmp->lowercase[idx];
}else{
if(tmpchar >= 'A' && tmpchar <= 'Z'){
idx = tmpchar - 'A';
if(!tmp->uppercase[idx]) tmp->uppercase[idx] = new TrieNode();
tmp = tmp->uppercase[idx];
}else {
idx = tmpchar - 'a';
if(!tmp->lowercase[idx]) tmp->lowercase[idx] = new TrieNode();
tmp = tmp->lowercase[idx];
}
}
}
if(case_sensitive){
tmp->word = wordlist[i];
}else {
tmp->wordlist.push_back(wordlist[i]);
}
}
}
bool hasword(string word, string& foundword, bool case_sensitive = true){
TrieNode* tmp = root;
locale loc;
for(int i=; i<word.size(); i++){
char tmpchar = word[i];
int idx = ;
if(!case_sensitive){
tmpchar = tolower(tmpchar, loc);
idx = tmpchar - 'a';
if(!tmp->lowercase[idx]) return false;
tmp = tmp->lowercase[idx];
}else {
if(tmpchar >= 'A' && tmpchar <= 'Z') {
idx = tmpchar - 'A';
if(!tmp->uppercase[idx]) return false;
tmp = tmp->uppercase[idx];
} else {
idx = tmpchar - 'a';
if(!tmp->lowercase[idx]) return false;
tmp = tmp->lowercase[idx];
}
}
}
if(!case_sensitive) {
if(!tmp->wordlist.empty()){
foundword = tmp->wordlist[];
return true;
}
return false;
}
if(!tmp->word.empty()) {
foundword = tmp->word;
return true;
}
return false;
}
}; class Solution {
public:
set<char> vset;
unordered_map<string,int> mp;
vector<string> spellchecker(vector<string>& wordlist, vector<string>& queries) {
for(int i=; i<wordlist.size(); i++){
mp[wordlist[i]] = i;
}
vset.insert('a');vset.insert('e');vset.insert('i');
vset.insert('o');vset.insert('u');
vector<string> ret;
Trie trie_case_sensi = Trie(wordlist);
Trie trie_not_case_sensi = Trie(wordlist, false);
for(int i=; i<queries.size(); i++){
string foundword;
vector<string> foundwordvec;
if(trie_case_sensi.hasword(queries[i],foundword)) {
ret.push_back(queries[i]);
}else if(trie_not_case_sensi.hasword(queries[i], foundword, false)){
ret.push_back(foundword);
}else {
dfs(trie_not_case_sensi.root, queries[i], foundwordvec, );
int minidx = wordlist.size();
for(auto x : foundwordvec) minidx = min(minidx, mp[x]);
if(minidx == wordlist.size()) ret.push_back("");
else ret.push_back(wordlist[minidx]);
}
}
return ret;
} void dfs(const TrieNode* root,string query, vector<string>& ret, int start){
if(start == query.size()){
assert(!root->wordlist.empty());
ret.push_back(root->wordlist[]);
return ;
}
std::locale loc;
char c = tolower(query[start],loc);
int idx = ;
idx = c - 'a';
if(vset.count(c)){
for(auto it = vset.begin(); it != vset.end(); it++){
char vsub = *it;
int newidx = ;
newidx = vsub - 'a';
if(!root->lowercase[newidx]) continue;
TrieNode* nextroot = root->lowercase[newidx];
dfs(nextroot, query, ret, start+);
}
}else{
if(!root->lowercase[idx]) return ;
TrieNode* nextroot = root->lowercase[idx];
dfs(nextroot, query, ret, start+);
}
}
};

下面看看网上的大神的解法,很简单,既然aeiou都能互相匹配,那就把aeiou变成#,这样一来不就行了么!真是厉害。

class Solution {
public String[] spellchecker(String[] wordlist, String[] queries) {
Set<String> words = new HashSet<>(Arrays.asList(wordlist));
HashMap<String, String> cap = new HashMap<>();
HashMap<String, String> vowel = new HashMap<>();
for (String w : wordlist) {
String lower = w.toLowerCase(), devowel = lower.replaceAll("[aeiou]", "#");
cap.putIfAbsent(lower, w);
vowel.putIfAbsent(devowel, w);
}
for (int i = ; i < queries.length; ++i) {
if (words.contains(queries[i])) continue;
String lower = queries[i].toLowerCase(), devowel = lower.replaceAll("[aeiou]", "#");
if (cap.containsKey(lower)) {
queries[i] = cap.get(lower);
} else if (vowel.containsKey(devowel)) {
queries[i] = vowel.get(devowel);
} else {
queries[i] = "";
}
}
return queries;
}
}

LC 966. Vowel Spellchecker的更多相关文章

  1. 【leetcode】966. Vowel Spellchecker

    题目如下: Given a wordlist, we want to implement a spellchecker that converts a query word into a correc ...

  2. 【LeetCode】966. Vowel Spellchecker 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典 日期 题目地址:https://leetcod ...

  3. [Swift]LeetCode966.元音拼写检查器 | Vowel Spellchecker

    Given a wordlist, we want to implement a spellchecker that converts a query word into a correct word ...

  4. Weekly Contest 117

    965. Univalued Binary Tree A binary tree is univalued if every node in the tree has the same value. ...

  5. 【Leetcode周赛】从contest-111开始。(一般是10个contest写一篇文章)

    Contest 111 (题号941-944)(2019年1月19日,补充题解,主要是943题) 链接:https://leetcode.com/contest/weekly-contest-111 ...

  6. Swift LeetCode 目录 | Catalog

    请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift    说明:题目中含有$符号则为付费题目. 如 ...

  7. 四种比较简单的图像显著性区域特征提取方法原理及实现-----> AC/HC/LC/FT。

    laviewpbt  2014.8.4 编辑 Email:laviewpbt@sina.com   QQ:33184777 最近闲来蛋痛,看了一些显著性检测的文章,只是简单的看看,并没有深入的研究,以 ...

  8. “LC.exe”错误

    错误“LC.exe”已退出,代码为 -1. 可能的原因是: 这个第三方组件是个商业组件,他在组件的主使用类定义了 LicenseProvider(typeof(LicFileLicenseProvid ...

  9. 解决VS下“LC.exe已退出,代码为-1”问题

    今天使用VS2015开发一个Winform程序,手一抖拖错了一个第三方控件,然后将其去掉并删除相关的引用,结果导致了LC.exe错误:"Lc.exe已退出,代码为-1 ". 经过上 ...

随机推荐

  1. Oracle笔记(九) 表的创建及管理

    对于数据库而言实际上每一张表都表示的是一个数据库的对象,而数据库对象指的就是DDL定义的所有操作,例如:表.视图.索引.序列.约束等等,都属于对象的操作,所以表的建立就是对象的建立,而对象的操作主要分 ...

  2. ubuntu安装软件apt-get

    一. apt-get用法 apt 0.8.16~exp12ubuntu10.26 for i386 compiled on Aug  5 2015 19:06:21Usage: apt-get [op ...

  3. Go语言基础之Cookie和Session

    Cookie和Session Cookie和Session是Web开发绕不开的一个环节,本文介绍了Cookie和Session的原理及在Go语言中如何操作Cookie. Cookie Cookie的由 ...

  4. 数据库——Oracle(5)

    1 唯一约束: 1)修改表的时候设置唯一约束 alter table 表名 add constraint 约束名 unique(列名1,列名2,列名3...) create table worker8 ...

  5. SQL Server中四类事务并发问题的实例再现(转)

    本篇文章将用实例再现数据库访问中四类并发问题,希望能让初学者能对事务的并行性有进一步的理解. 首先,让我们先来了解一下并行问题以及事务隔离级别这两个概念.在数据库中,假设如果没有锁定且多个用户同时访问 ...

  6. Java运行环境绿色部署配置

    这个Java的绿色安装配置,还有从未自己的使用电脑说起来. 最近电脑运行慢,很长时间没有清理及维护了,而且有可能中毒或木马了,所以就把系统进行了Ghost还原了,所以原来安装的jdk环境也无法使用了, ...

  7. Python模块struct(二进制数据服务)

    struct模块 Python没有专门处理字节的数据类型.但由于b'str'可以表示字节,所以,字节数组=二进制str. 而在C语言中,我们可以很方便地用struct.union来处理字节,以及字节和 ...

  8. Springboot定时任务实现动态配置Cron参数(从外部数据库获取)

    https://blog.csdn.net/qq_35992900/article/details/80429245 我们主要讲解它的动态配置使用方法. 在刚开始使用的时候,我们更改一个任务的执行时间 ...

  9. idea操作mysql数据库添加汉字时出现乱码解决方案

    首先 然后 最后 在连接数据库后面加一个指定编码格式 编码格式: characterEncoding=UTF-8

  10. Acwing-203-同余方程(扩展欧几里得)

    链接: https://www.acwing.com/problem/content/205/ 题意: 求关于x的同余方程 ax ≡ 1(mod b) 的最小正整数解. 思路: 首先:扩展欧几里得推导 ...