最近尝试完全脱离C++,转而只用java刷题。这是我用java做出的第一道树。题目在这里。说几点做题思路。
1. 暴力用Hashtable存单词,显然浪费空间,每个字母每个位次应该只存一次。暴力用Regex匹配,只适用于Hash字典。每个字母每个位次只存一次,在脑子里想一下,就能想到这就是要建一棵26叉树。
2. TreeNode除了字母值和大小为26的TreeNode数组外,还应包含一个整数min,用于表示当前字母到该分支最短单词最后一个字母的长度,例如存abc,那么字母b的min应为1,表示查找的时候,还需要再向下查一层才行,否则,查找ab的时候就会返回真,而事实上我们并未存储过ab这个单词。
3. Tree结构的查找用的是典型的递归查找。匹配’.’与匹配其他26个字母的不同,在于我需要查找当前TreeNode的所有非空的子树,且只要一棵子树查找成功即可。
4. 最重要的是TreeNode类的设计:
public class TreeNode {
char val;
int min;
TreeNode[] next;
TreeNode(char c) {
val = c;
next = new TreeNode[26];
}
}
其中最重要的是TreeNode的构造函数,当我们执行
next = new TreeNode[26];
时,我们仅仅声明了next数组的大小,而并未分配内存,而这正是我们想要的。(如果你创建了一个非基本类型的数组,那么你就创建了一个引用数组。-《Java编程思想》5.8 数组初始化)
贴代码:
public class WordDictionary {
public class TreeNode {
char val;
int min;
TreeNode[] next;
TreeNode(char c) {
val = c;
next = new TreeNode[26];
}
}
public TreeNode root;
public WordDictionary() {
root = new TreeNode(' ');
}
// Adds a word into the data structure.
public void addWord(String word) {
int len = word.length();
int i;
int index;
char c;
TreeNode current = root;
int min_len = len;
for (i=0;i<len;i++) {
min_len--;
c = word.charAt(i);
index = (int)(c - 97);
if (current.next[index]==null) {
current.next[index] = new TreeNode(c);
current.next[index].min = min_len;
}
else if (current.next[index].min>min_len) current.next[index].min = min_len;
current = current.next[index];
}
}
// 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) {
return searchTree(word, root);
}
public boolean searchTree(String word, TreeNode current) {
int len = word.length();
if(len==0) {
if (current.min>0) return false;
else return true;
}
char c = word.charAt(0);
if (c!='.') {
int index = (int)(c-97);
if (current.next[index]==null) return false;
else if (current.next[index].val!=c) return false;
else {
return searchTree(word.substring(1), current.next[index]);
}
}
else {
int i;
for (i=0;i<26;i++) {
if (current.next[i]!=null) {
if (searchTree(word.substring(1), current.next[i])==true) return true;
}
}
return false;
}
}
}
// Your WordDictionary object will be instantiated and called as such:
// WordDictionary wordDictionary = new WordDictionary();
// wordDictionary.addWord("word");
// wordDictionary.search("pattern");