Add and Search Word – Data structure design
Design a data structure that supports the following two operations:
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
解题思路
显然需要实现一棵trie树来存储所有的word,而查找word的过程,就是对trie树节点的遍历。
考虑到字符’.’代表任意字符,所以需要遍历当前trie树节点的所有子节点。
为了节约内存开销,采用bit位来表示当前节点所包含的字符。例如:
0001 -> ‘a’
0010 -> ‘b’
0101 -> ‘ca’
java代码
public class WordDictionary {
Node dict = new Node();
boolean existNull = false; // 是否存在 word == null
boolean existBlankWord = false; // 是否存在 word == ""
static class Node{
int vals = 0; // vals的 0-26位,分别代表'a'-'z'字符是否存在。
int ends = 0; // ends的 0-26位,分别代表是否存在word以'a'-'z'字符结尾。
Node[] subs = new Node[26]; // 子节点
}
// Adds a word into the data structure.
public void addWord(String word) {
if(word == null){
existNull = true;
return;
}
if("".equals(word)){
existBlankWord = true;
return;
}
addWord(word,0, dict);
}
private void addWord(String word, int pos, Node node) {
if( pos >= word.length())
return;
int v = word.charAt(pos) - 'a';
node.vals |= (1<<v);
if(pos == word.length()-1){
node.ends |= (1<<v);
}
if(node.subs[v] == null){
node.subs[v] = new Node();
}
addWord(word, pos+1, node.subs[v]);
}
// 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) {
if(word == null)
return existNull;
if("".equals(word)){
return existBlankWord;
}
return search(word, 0, dict);
}
private boolean search(String word, int pos, Node node){
if(node == null){
return false;
}
char ch = word.charAt(pos);
if(pos == word.length()-1){
if(ch == '.'){
return node.ends != 0;
}else{
int v = ch - 'a';
return (node.ends & (1<<v)) != 0;
}
}
if(ch == '.'){
int vals = node.vals;
for(int i=0; i<26; i++){
if((vals & (1<<i)) != 0 && search(word, pos+1, node.subs[i]))
return true;
}
return false;
}else{
int v = ch - 'a';
if((node.vals & (1<<v)) == 0)
return false;
else
return search(word, pos+1, node.subs[v]);
}
}
}
// Your WordDictionary object will be instantiated and called as such:
// WordDictionary wordDictionary = new WordDictionary();
// wordDictionary.addWord("word");
// wordDictionary.search("pattern");