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"
- Example:
- 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)
- Example:
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
andqueries
consist only of english letters.
這道題給了一組單詞,讓實現一個拼寫檢查器,把查詢單詞轉換成一個正確的單詞。這個拼寫檢查器主要有兩種功能,一種是可以忽略大小寫,另一種是忽略元音的錯誤,所謂元音是 a,e,i,o,u,這五個字母。另外題目中還制定了一些其他規則:假如有和查詢單詞一模一樣的單詞,考慮大小寫,此時應該優先返回。第二個優先級是字母及順序都一樣,但大小寫可能不同的,第三個優先級是有元音錯誤的單詞也可以返回,最后都不滿足的話返回空串。首先對於第一種情況,返回和查詢單詞一模一樣的單詞,很簡單,將所有單詞放入一個 HashSet 中,這樣就可以快速確定一個查詢單詞是否在原單詞數組中出現過。對於第二種情況,做法是將每個單詞都轉為小寫,然后建立小寫單詞和原單詞之間都映射,注意對於轉為小寫后相同都單詞,我們只映射第一個出現該小寫狀態的單詞,后面的不用管。對於第三種情況,對於每個單詞,轉為小寫之后,然后把所有的元音字母用特殊字符替代,比如下划線,然后也是建立這種特殊處理后的狀態和原單詞之間的映射。當映射都建立好了之后,就可以遍歷所有的查詢單詞了,首先是去 HashSet 中找,若有跟該查詢單詞一模一樣的,直接加入結果 res 中。若沒有,則先將查詢單詞變為小寫,然后去第一個 HashMap 中查找,若存在,直接加入結果 res 中。若沒有,再把所有的元音變為下划線,去第二個 HashMap 中查找,存在則直接加入結果 res 中。若沒有,則將空串加入結果 res 中,參見代碼如下:
解法一:
class Solution {
public:
vector<string> spellchecker(vector<string>& wordlist, vector<string>& queries) {
vector<string> res;
unordered_set<string> st;
unordered_map<string, string> m1;
unordered_map<string, string> m2;
for (int i = 0; i < wordlist.size(); ++i) {
string word = wordlist[i];
st.insert(word);
transform(word.begin(), word.end(), word.begin(), ::tolower);
if (!m1.count(word)) m1[word] = wordlist[i];
for (char &c : word) {
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') c = '_';
}
if (!m2.count(word)) m2[word] = wordlist[i];
}
for (string query : queries) {
if (st.count(query)) {
res.push_back(query);
continue;
}
transform(query.begin(), query.end(), query.begin(), ::tolower);
if (m1.count(query)) {
res.push_back(m1[query]);
continue;
}
for (char &c : query) {
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') c = '_';
}
if (m2.count(query)) {
res.push_back(m2[query]);
continue;
}
res.push_back("");
}
return res;
}
};
討論:這里博主不得不吐槽一下 C++ 的STL的功能實在不如 Java 強大,若用 Java 寫的話,可以直接調用 toLowerCase()
來轉小寫,同時可以用 replaceAll()
來快速替換元音,而 C++ 就顯得很笨拙了,哎,誰讓博主就是用 C++ 刷的順手呢~
Github 同步地址:
https://github.com/grandyang/leetcode/issues/966
參考資料:
https://leetcode.com/problems/vowel-spellchecker/
https://leetcode.com/problems/vowel-spellchecker/discuss/211189/JavaC%2B%2BPython-Two-HashMap