Tries Data Structure
Implement Tries with Array
1. insert - insert a string if the string doesn't exist, nop otherwise
2. contains - check if input String exists in the Tries
3. autocomplete - return all words which contain input String as suffix

public  void add(TNode r, int[] arr, int k) {
if( k < arr.length) {
if(r.array[arr[k]] == null)
r.array[arr[k]] = new TNode();

}else if(k == arr.length){
r.isWord = true;
}
}

public  boolean contains(TNode r, int[] arr, int h) {
if(r != null){
if(h < arr.length) {
return contains(r.array[arr[h]], arr, h+1);
}else if (h == arr.length){
return r.isWord;
}
}
return false;
}
public  void addWord(TNode r,  String word, int k) {
if( k < word.length()) {
if(r.array[map(word.charAt(k))] == null)
r.array[map(word.charAt(k))] = new TNode();

}else{
r.isWord = true;
}
}
public  boolean containsWord(TNode r, String word, int k) {
if(r != null){
if(k == word.length())
return r.isWord;
else if(k < word.length()){
return containsWord(r.array[map(word.charAt(k))], word, k+1);
}
}
return false;
}


Implement Tries with HashMap
1. insert
2. contains
3. autocomplete

/**
* insert str to Tries from the root, if str doesn't exist in Tries
* set isWord to be true, and assign str to word
* if str does exist in the tries, do nothing
*
* @param root   the root node of Tries, it can't be null
* @param str    the String is being inserted
* @param index  index of str, initial value is zero
*
* return void
*/
public static void insert(XNode root, String str, int index) {
if(index == str.length()) {
root.isWord = true;
root.word = str;
} else {
char ch = str.charAt(index);
XNode node = root.map.get(ch);
if(node == null) {
node = new XNode(false);
root.map.put(ch, node);
}
insert(node, str, index+1);
}
}

/**
* check if the str exist in the Tries,
*
* @param root the root of Tries
* @param str  the String to be checked
* @param index index of str
*
* @return true if str exists in the Tries, false otherwise
*/
public static boolean contains(XNode root, String str, int index) {
if(index == str.length()) {
return root.isWord;
} else {
if(root.map.containsKey(str.charAt(index))) {
return contains(root.map.get(str.charAt(index)), str, index + 1);
} else {
return false;
}
}
}

public static XNode autocomplete(XNode root, String partialWord, int index) {
if(index == partialWord.length()) {
return root;
}else {
XNode node = root.map.get(partialWord.charAt(index));
if(node != null) {
return autocomplete(node, partialWord, index + 1);
}
return null;
}
}
public static void autocompleteList(XNode node, String partialWord, int index, List<String> list) {
if(node.isWord)