Implement a trie with
insert
,search
, andstartsWith
methods.
Example:
Trie trie = new Trie();
trie.insert("apple");
trie.search("apple"); // returns true
trie.search("app"); // returns false
trie.startsWith("app"); // returns true
trie.insert("app");
trie.search("app"); // returns true
Note:
You may assume that all inputs are consist of lowercase letters a-z.
All inputs are guaranteed to be non-empty strings.
解釋下題目:
實現一個類,這個類能夠增加一個字符串,然后能夠搜索這個字符串,以及能夠搜索整個類中有沒有以xxx開頭的字符串。
1. 鏈表
實際耗時:77ms
class TrieNode {
private static final char MY_NULL = ' ';
public char val;
public boolean flag = false;
public TrieNode[] children = new TrieNode[26];
public TrieNode() {
this.val = MY_NULL;
}
public TrieNode(char c) {
TrieNode tn = new TrieNode();
tn.val = c;
}
}
public class Trie {
private TrieNode root;
/**
* Initialize your data structure here.
*/
public Trie() {
root = new TrieNode();
}
/**
* Inserts a word into the trie.
*/
public void insert(String word) {
TrieNode cur = root;
for (char c : word.toCharArray()) {
if (cur.children[c - 'a'] != null) {
} else {
cur.children[c - 'a'] = new TrieNode(c);
}
cur = cur.children[c - 'a'];
}
cur.flag = true;
}
/**
* Returns if the word is in the trie.
*/
public boolean search(String word) {
TrieNode cur = root;
for (char c : word.toCharArray()) {
if (cur.children[c - 'a'] != null) {
cur = cur.children[c - 'a'];
} else {
return false;
}
}
return cur.flag;
}
/**
* Returns if there is any word in the trie that starts with the given prefix.
*/
public boolean startsWith(String prefix) {
TrieNode cur = root;
for (char c : prefix.toCharArray()) {
if (cur.children[c - 'a'] != null) {
cur = cur.children[c - 'a'];
} else {
return false;
}
}
return true;
}
public static void main(String[] args) {
Trie trie = new Trie();
trie.insert("apple");
System.out.println(trie.search("apple")); // returns true
System.out.println(trie.search("app")); // returns false
System.out.println(trie.startsWith("app")); // returns true
trie.insert("app");
System.out.println(trie.search("app")); // returns true
}
}
??思路:一開始拿到這道題,看到又有插入,又有搜索,所以覺得LinkedList應該是蠻不錯的解法。但是又看到startWith,如果用LinkedList來實現,那肯定完蛋,因為你要每個答案都去遍歷一遍,時間復雜度太高了。然后就這樣想到了可不可以用樹來解決呢,其實一開始我把自己否認了,因為就算題目說了只有小寫字母,那樹的復雜度也高達 26^n ,其中n為最長的單詞的長度,這其實也是非常恐怖的,但是看到題目里就有Prefix Tree,估計也就是這么做了。
?? 一路寫下來其實還挺好,最后卡在了apple和app判斷上,我之前做search的時候,判斷的依據是,看這個單詞的最后一個字母后面還有沒有了,如果有,則說明這個單詞只是前綴,不滿足search的完整性要求,但是后來發現如果同時有apple和app,我這種判斷apple是沒問題的,但是判斷app就錯了,所以之后改了一下,在加入的時候用一個flag來判斷以這個節點為最后節點的是不是一個單詞,這樣也省掉了最后的判斷。