void addWord(word) bool search(word)search(word) can search a literal word or a regular expression string containing only letters
a-z
or .
. A .
means it can represent any one letter.For example:
addWord("bad") addWord("dad") addWord("mad") search("pad") -> false search("bad") -> true search(".ad") -> true search("b..") -> true
Naive Thinking: Similar to Implement Trie(prefix-tree) . But pattern '.' was included. For addWord() method, '.' doesn't affect the process since its not necessary to combine '.ad' and 'bad'. It's okay to leave both in the tree. While for search() method, when '.' appear in the word, we need to search all child nodes. when '.' appear in the node, we need to search this node also. So I apply a DFS approach to do search().
public class WordDictionary {
LetterNode head = new LetterNode('*');
// Adds a word into the data structure.
public void addWord(String word) {
LetterNode cur = head;
for(int i = 0;i < word.length();i++){
if(cur.next.containsKey(word.charAt(i))){
cur = cur.next.get(word.charAt(i));
}else{
LetterNode son = new LetterNode(word.charAt(i));
cur.next.put(word.charAt(i), son);
cur = son;
}
}
cur.isEnd = true;
}
// Returns if the word is in the data structure. A word could
// contain the dot character '.' to represent any one letter.
public boolean search(String word) {
// DFS
return search(head, word, 0);
}
private boolean search(LetterNode node, String word, int layer){
LetterNode son = null, dot = null;
// ending case
if(node == null) return false;
if(layer == word.length()) return node.isEnd;
// general case
if(word.charAt(layer)=='.'){
// Go though all next nodes when '.' appear
Iterator iter = node.next.entrySet().iterator();
while(iter.hasNext()){
Map.Entry pair = (Map.Entry)iter.next();
if(search((LetterNode)pair.getValue(), word, layer+1))
return true;
}
}else{
// Go though target character nodes and '.' nodes
if(node.next.containsKey(word.charAt(layer)))
son = node.next.get(word.charAt(layer));
if(node.next.containsKey('.'))
dot = node.next.get('.');
if(son!=null || dot!=null)
return search(son, word, layer+1) || search(dot, word, layer+1);
}
return false;
}
class LetterNode{
Map<Character, LetterNode> next;
char letter;
boolean isEnd;
LetterNode(char c){
this.letter = c;
this.next = new HashMap<Character, LetterNode>();
this.isEnd = false;
}
}
}
// Your WordDictionary object will be instantiated and called as such:
// WordDictionary wordDictionary = new WordDictionary();
// wordDictionary.addWord("word");
// wordDictionary.search("pattern");
No comments:
Post a Comment