It is the second algorithm in one of mock interviews on Leetcode.com. I worked on the solution and it took me over one hour to fix it. Because I ran into timeout issue on test case 48/53, I had to review my code to preprocess a few hashSet and hashMap to expedite the lookup.
Here are highlights:
- First, put all words in wordList into a hashSet, so it can use O(1) time to look up; if it is found, then no spell check need;
- Next, preprocess a hashSet with lower case word, and also a hashmap to map the lower case word to its original words, for example, key string "kite", value strings {"KiTe","kite"}.
- Thirdly, preprocess a hashSet with vowel char replaced, for example, "kite" has two vowel char 'i' and 'e' which can be replaced using '*', so "k*t*" can be a key string to represent all vowel error words.
- Will continue to add more detail. Stay tuned.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace spellCheckerProject
{
class Program
{
static void Main(string[] args)
{
var wordList = new string[] { "KiTe", "kite", "hare", "Hare" };
var queries = new string[] { "kite", "Kite", "KiTe", "Hare", "HARE", "Hear", "hear", "keti", "keet", "keto" };
var result = Spellchecker(wordList, queries);
}
/// <summary>
/// spellchecker
/// Oct. 11, 2019
/// Timeout bug - need to continue to work on
/// </summary>
/// <param name="wordlist"></param>
/// <param name="queries"></param>
/// <returns></returns>
public static string[] Spellchecker(string[] wordlist, string[] queries)
{
var lengthWord = wordlist.Length;
var lengthQuery = queries.Length;
var hashset = new HashSet<string>(wordlist);
var lowerHashset = new HashSet<string>();
var map = new Dictionary<string, List<string>>();
foreach (var item in wordlist)
{
var key = item.ToLower();
lowerHashset.Add(key);
if (!map.ContainsKey(key))
{
map.Add(key, new List<string>());
}
map[key].Add(item);
}
var vowelSet = new HashSet<string>();
var vowels = new HashSet<char>("aeiou".ToCharArray());
var vowelMap = new Dictionary<string, string>();
foreach (var item in wordlist)
{
var replaced = vowelReplaced(item);
vowelSet.Add(replaced);
if(!vowelMap.ContainsKey(replaced))
{
vowelMap.Add(replaced, item);
}
}
var matchingWords = new string[lengthQuery];
for (int i = 0; i < lengthQuery; i++)
{
var current = queries[i];
var currentLower = current.ToLower();
if (hashset.Contains(current))
{
matchingWords[i] = current;
continue;
}
// Capitalization
var capitalization = false;
if (lowerHashset.Contains(currentLower))
{
matchingWords[i] = map[currentLower][0];
capitalization = true;
}
if (capitalization)
{
continue;
}
// Vowel errors
var vowelErrors = false;
var replacedKey = vowelReplaced(currentLower);
if(vowelSet.Contains(replacedKey))
{
matchingWords[i] = vowelMap[replacedKey];
vowelErrors = true;
}
// edge case - no matching
if (!vowelErrors)
{
matchingWords[i] = "";
}
}
return matchingWords;
}
/// <summary>
/// convert to lower case, and then replace vowel char
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
private static string vowelReplaced(string item)
{
var vowels = new HashSet<char>("aeiou".ToCharArray());
var array = item.ToLower().ToCharArray();
for (int i = 0; i < array.Length; i++)
{
var vowelCheck = array[i];
if (vowels.Contains(vowelCheck))
{
array[i] = '*';
}
}
return new string(array);
}
private static bool isMatchingVowelError(string matching, string source)
{
if (matching.Length != source.Length)
return false;
var vowels = new HashSet<char>("aeiou".ToCharArray());
for (int i = 0; i < matching.Length; i++)
{
var current = matching[i];
var sourceChar = source[i];
if (vowels.Contains(current) != vowels.Contains(sourceChar))
{
return false;
}
if (!vowels.Contains(current) && current != sourceChar)
{
return false;
}
}
return true;
}
}
}
No comments:
Post a Comment