> ## Documentation Index
> Fetch the complete documentation index at: https://leetcode-py.wisl.dev/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> leetcode-py is a Python LeetCode practice environment generator with one CLI: lcpy. It is not a service or platform.
> Each problem is a directory under leetcode/ with README.md, solution.py, test_solution.py, helpers.py, and playground.ipynb. lcpy gen creates them from JSON templates bundled with the package.
> Examples are backed by tests; copy them verbatim.

# Vowel Spellchecker Python Solution with Tests

> Tested Python solution for LeetCode 966 with 18 pytest cases. Generate a practice environment with lcpy.

LeetCode 966, [Medium](/catalog/medium). Topics: [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string). [View on LeetCode](https://leetcode.com/problems/vowel-spellchecker/description/).

Generate this problem as a practice environment: tested reference solution, 18 [parametrized pytest cases](/practice/testing), and a playground notebook:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 966   # by problem number
lcpy gen -s vowel_spellchecker   # by problem name
```

## Problem

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.
* 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.

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 capitalization, 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]`.

### Examples

```
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"]
```

```
Input: wordlist = ["yellow"], queries = ["YellOw"]
Output: ["yellow"]
```

### Constraints

* 1 \<= wordlist.length, queries.length \<= 5000
* 1 \<= wordlist\[i].length, queries\[i].length \<= 7
* wordlist\[i] and queries\[i] consist only of English letters.

## Solution

Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/vowel_spellchecker/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/vowel_spellchecker/test_solution.py):

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
    # Time: O((W + Q) * L) where W = len(wordlist), Q = len(queries), L = max word length
    # Space: O(W * L)
    def spellchecker(self, wordlist: list[str], queries: list[str]) -> list[str]:
        vowels = set("aeiou")

        def mask(word: str) -> str:
            return "".join("*" if c in vowels else c for c in word.lower())

        words = set(wordlist)
        case_insensitive: dict[str, str] = {}
        vowel_insensitive: dict[str, str] = {}
        for word in wordlist:
            case_insensitive.setdefault(word.lower(), word)
            vowel_insensitive.setdefault(mask(word), word)

        answer: list[str] = []
        for query in queries:
            if query in words:
                answer.append(query)
            elif query.lower() in case_insensitive:
                answer.append(case_insensitive[query.lower()])
            elif mask(query) in vowel_insensitive:
                answer.append(vowel_insensitive[mask(query)])
            else:
                answer.append("")
        return answer
```

## Complexity

| Time | Space |
| - | - |
| O((W + Q) \* L) where W = len(wordlist), Q = len(queries), L = max word length | O(W \* L) |

## Tags


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.