966. Vowel Spellchecker (javascript solution)
Tags: algorithms, javascript
Published: 2021-03-22 23:50:23

###Description:
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].

###Solution:
Time Complexity : O(n)
Space Complexity: O(n)

```javascript
// There are 3 different cases to look for
// Account for each case in 3 specialized maps, 1 for each case
// Check if each query in queries is in one of the 3 maps
var spellchecker = function(wordlist, queries) {
    // Create 3 maps
    let words_perfect = new Set();
    let words_cap = new Map();
    let words_vow = new Map();
    
    // Populate maps
    for (const word of wordlist) {
        words_perfect.add(word);

        const wordlow = word.toLowerCase();
        if(!words_cap.has(wordlow)) words_cap.set(wordlow, word);


        const wordlowDV = devowel(wordlow);
        if(!words_vow.has(wordlowDV)) words_vow.set(wordlowDV, word);
    }
    
    // Function to check if a query is present in any of the maps
    function solve(query) {
        if (words_perfect.has(query))
            return query;

        const queryL = query.toLowerCase();
        if (words_cap.has(queryL))
            return words_cap.get(queryL);

        const queryLV = devowel(queryL);
        if (words_vow.has(queryLV))
            return words_vow.get(queryLV);

        return "";
    }
    
    let ans = Array(queries.length);
    let t = 0;
    for (const query of queries)
        ans[t++] = solve(query);
    return ans;
};


// Remove all vowels from a word
function devowel(word) {
    let ans = '';
    for (const c of word)
        ans += isVowel(c) ? '*' : c;
    return ans;
}

function isVowel(c) {
    return (c === 'a' || c === 'e' || c === 'i' || c === 'o' || c === 'u');
}
```