diff --git a/Leetcode.iml b/Leetcode.iml
new file mode 100644
index 0000000000..4e93bcaf2f
--- /dev/null
+++ b/Leetcode.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 0903d6222e..dd04e4f796 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,8 @@ Your ideas/fixes/algorithms are more than welcome!
| # | Title | Solutions | Time | Space | Video | Difficulty | Tag
|-----|----------------|---------------|---------------|---------------|--------|-------------|-------------
-|965|[Univalued Binary Tree](https://leetcode.com/problems/univalued-binary-tree/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_965.java) | O(n) | O(h) | |Easy| DFS, recursion
+|966|[Vowel Spellchecker](https://leetcode.com/problems/vowel-spellchecker/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_966.java) | O(hlogn) | O(n) | |Medium| Hash Table, String
+|965|[Univalued Binary Tree](https://leetcode.com/problems/univalued-binary-tree/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_965.java) | O(n) | O(h) | |Easy| DFS, recursion|
|961|[N-Repeated Element in Size 2N Array](https://leetcode.com/problems/n-repeated-element-in-size-2n-array/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_961.java) | O(n) | O(1) | |Easy|
|944|[Delete Columns to Make Sorted](https://leetcode.com/problems/delete-columns-to-make-sorted/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_944.java) | O(n) | O(1) | |Easy|
|941|[Valid Mountain Array](https://leetcode.com/problems/valid-mountain-array/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_941.java) | O(n) | O(1) | |Easy|
diff --git a/src/main/java/com/fishercoder/solutions/_966.java b/src/main/java/com/fishercoder/solutions/_966.java
new file mode 100644
index 0000000000..b4097abff5
--- /dev/null
+++ b/src/main/java/com/fishercoder/solutions/_966.java
@@ -0,0 +1,91 @@
+package com.fishercoder.solutions;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 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].
+ *
+ * */
+
+public class _966 {
+
+ public static class Solution {
+ public String[] spellchecker(String[] wordlist, String[] queries) {
+ Map caseMap = new HashMap<>();
+ Set set = new HashSet<>();
+
+ // Case Part Mapping
+ for (String word : wordlist) {
+ if (!caseMap.containsKey(word.toLowerCase())) {
+ caseMap.put(word.toLowerCase(), word);
+ }
+
+ set.add(word);
+ }
+
+ // Vowel Part Mapping
+ Map vowelMap = new HashMap<>();
+ for (String word : wordlist) {
+ String genericVal = makeGenericVowel(word);
+ if (!vowelMap.containsKey(genericVal)) {
+ vowelMap.put(genericVal, word);
+ }
+ }
+
+ String[] ans = new String[queries.length];
+
+ for (int i = 0; i < queries.length; i++) {
+ if (set.contains(queries[i])) {
+ ans[i] = queries[i];
+ }
+ else if (caseMap.containsKey(queries[i].toLowerCase())) {
+ ans[i] = caseMap.get(queries[i].toLowerCase());
+ }
+ else if (vowelMap.containsKey(makeGenericVowel(queries[i]))) {
+ ans[i] = vowelMap.get(makeGenericVowel(queries[i]));
+ }
+ else {
+ ans[i] = "";
+ }
+ }
+
+ return ans;
+ }
+
+ private String makeGenericVowel(String s) {
+ String vowel = "aeiou";
+ char[] ch = s.toLowerCase().toCharArray();
+ for (int i = 0; i < ch.length; i++) {
+ if (vowel.indexOf(ch[i]) != -1) {
+ ch[i] = '#';
+ }
+ }
+
+ return String.valueOf(ch);
+ }
+ }
+}
diff --git a/src/test/java/com/fishercoder/_966Test.java b/src/test/java/com/fishercoder/_966Test.java
new file mode 100644
index 0000000000..0ccb874586
--- /dev/null
+++ b/src/test/java/com/fishercoder/_966Test.java
@@ -0,0 +1,34 @@
+package com.fishercoder;
+
+import com.fishercoder.solutions._966;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Created by varunu28 on 1/01/19.
+ */
+
+
+public class _966Test {
+ private static _966.Solution test;
+
+ @BeforeClass
+ public static void setup() {
+ test = new _966.Solution();
+ }
+
+
+ @Test
+ public void test1() {
+ assertEquals(
+ Arrays.toString(new String[]{"kite","KiTe","KiTe","Hare","hare","","","KiTe","","KiTe"}),
+ Arrays.toString(test
+ .spellchecker(
+ new String[]{"KiTe","kite","hare","Hare"},
+ new String[]{"kite","Kite","KiTe","Hare","HARE","Hear","hear","keti","keet","keto"})));
+ }
+}