classTrie{ // Node class privateclassNode{ Node[] next; boolean isKey; // indicate if it is an ending node Node(int r, boolean k) { next = new Node[r]; // R is 26 in this case isKey = k; } } // Members privatestaticfinalint R = 26; private Node root; // act as a dummy publicTrie(){ root = new Node(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; int n = s.length(); Node p = root; for (int i = 0; i < n; ++i) { char ch = s.charAt(i); if (ch < 'a' || ch > 'z') thrownew IllegalArgumentException("not a-z"); if (p.next[ch - 'a'] == null) { p.next[ch - 'a'] = new Node(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; int n = s.length(); Node p = root; for (int i = 0; i < n; ++i) { char ch = 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 = new ArrayList<>(); StringBuilder sb = new StringBuilder(); 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 (int i = 0; i < p.next.length; ++i) { Node nextNode = p.next[i]; char ch = (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){ int n = prefix.length(); Node p = root; for (int i = 0; i < n; ++i) { char ch = 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 = new ArrayList<>(); Node p = startsWithHelper(prefix); StringBuilder sb = new StringBuilder(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){ int n = s.length; StringBuilder sb = new StringBuilder(); // construct the prefix Node p = root; for (int i = 0; i < n; ++i) { char ch = 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(); }