classTrie { // Node class privateclassNode { Node[] next; boolean isKey; // indicate if it is an ending node Node(int r, boolean k) { next = newNode[r]; // R is 26 in this case isKey = k; } } // Members privatestaticfinalintR=26; private Node root; // act as a dummy publicTrie() { root = newNode(R, false); }
publicvoidinsert(String s) {} publicbooleansearch(String s) {} public List<String> collect() {} privatevoidcollectHelper(Node p, StringBuilder sb, List<String> result) {} publicbooleanstartsWith(String prefix) {} // similar to the code in search private Node startsWithHelper(String prefix) {} // return the last node if prefix matches. public List<String> wordsWithPrefix(String prefix) {} public String longestPrefixOf(String s) {} }
insert:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/* Inserts a word into the trie. */ publicvoidinsert(String s) { if (s == null || s.length() == 0) return; intn= s.length(); Nodep= root; for (inti=0; i < n; ++i) { charch= s.charAt(i); if (ch < 'a' || ch > 'z') thrownewIllegalArgumentException("not a-z"); if (p.next[ch - 'a'] == null) { p.next[ch - 'a'] = newNode(R, false); // false as default } p = p.next[ch - 'a']; // go to the current node if (i == n - 1) { // last one p.isKey = true; } }
search:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/** Contains a word */ publicbooleansearch(String s) { if (s == null || s.length() == 0) returntrue; intn= s.length(); Nodep= root; for (inti=0; i < n; ++i) { charch= s.charAt(i); // assume ch is ['a', 'z'] if (p.next[ch - 'a'] == null) returnfalse; p = p.next[ch - 'a']; if (i == n - 1) { // last one if (p.isKey == false) returnfalse; } } returntrue; }
/** Returns all the words is in the trie. */ public List<String> collect() { List<String> result = newArrayList<>(); StringBuildersb=newStringBuilder(); collectHelper(root, sb, result); return result; }
privatevoidcollectHelper(Node p, StringBuilder sb, List<String> result) { if (p == null) return; if (p.isKey) { result.add(sb.toString()); // do not return yet } for (inti=0; i < p.next.length; ++i) { NodenextNode= p.next[i]; charch= (char) ('a' + i); sb.append(ch); collectHelper(nextNode, sb, result); sb.setLength(sb.length() - 1); } }
startsWith:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/** Returns if there is any word in the trie that starts with the given prefix. */ // similar to the code in search publicbooleanstartsWith(String prefix) { if (prefix == null || prefix.length() == 0) returntrue; return startsWithHelper(prefix) != null; }
// return the last node if prefix matches. private Node startsWithHelper(String prefix) { intn= prefix.length(); Nodep= root; for (inti=0; i < n; ++i) { charch= prefix.charAt(i); // assume ch is ['a', 'z'] if (p.next[ch - 'a'] == null) returnnull; p = p.next[ch - 'a']; // don't care if the last node is key or not } return p; }
wordsWithPrefix:
1 2 3 4 5 6 7 8 9
/** Returns all words that start with the given prefix. */ public List<String> wordsWithPrefix(String prefix) { // find the node corresponding with the last char in prefix List<String> result = newArrayList<>(); Nodep= startsWithHelper(prefix); StringBuildersb=newStringBuilder(prefix); collectHelper(p, sb, result); return result; }
longestPrefixOf:
1 2 3 4 5 6 7 8 9 10 11 12 13
/** Returns the longest prefix of the word s. */ public String longestPrefixOf(String s) { intn= s.length; StringBuildersb=newStringBuilder(); // construct the prefix Nodep= root; for (inti=0; i < n; ++i) { charch= s.charAt(i); // assume ch is ['a', 'z'] if (p.next[ch - 'a'] == null) break; p = p.next[ch - 'a']; sb.append(ch); } return sb.toString(); }