Implement a trie with insert, search, and startsWith methods.
Note:
You may assume that all inputs are consist of lowercase letters a-z.All inputs are guaranteed to be non-empty strings.
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
1. 알고리즘을 해결하기 위해서 생각한 방법
- Trie라는 구조를 모르고 있었고, 해당 문제를 해결하기 위해서, LeetCode에서 제공하는 솔루션을 공부했습니다.
- Trie는 문자열을 저장하고, 특정 문자열이 존재하는 지, 빠르게 검색할 수 있는 자료구조입니다.
- 해당 문제에서는 insert, search, startsWith를 구현합니다.
2. 알고리즘 작성 중, 어려운 점
- 해당 문제를 어떤 자료구조로 접근해야할까?
3. 내가 작성한 알고리즘
class Trie {
Node root;
class Node{
Node[] node = new Node['z'-'a' + 1];
boolean isEnd = false;
}
/** Initialize your data structure here. */
public Trie() {
root = new Node();
}
/** Inserts a word into the trie. */
public void insert(String word) {
Node tmp = root;
for(int i=0; i<word.length(); i++){
if(tmp.node['z' - word.charAt(i)] == null){
tmp.node['z' - word.charAt(i)] = new Node();
}
tmp = tmp.node['z' - word.charAt(i)];
}
tmp.isEnd = true;
}
/** Returns if the word is in the trie. */
public boolean search(String word) {
Node tmp = root;
for(int i=0; i<word.length(); i++){
if(tmp.node['z' - word.charAt(i)] == null){
return false;
}
tmp = tmp.node['z' - word.charAt(i)];
}
return tmp.isEnd;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
public boolean startsWith(String prefix) {
Node tmp = root;
for(int i=0; i<prefix.length(); i++){
if(tmp.node['z' - prefix.charAt(i)] == null){
return false;
}
tmp = tmp.node['z' - prefix.charAt(i)];
}
return true;
}
}
/**
* Your Trie object will be instantiated and called as such:
* Trie obj = new Trie();
* obj.insert(word);
* boolean param_2 = obj.search(word);
* boolean param_3 = obj.startsWith(prefix);
*/
4. 알고리즘을 보고, 공부한 내용
- Insert : root 노드에 a-z까지의 소문자 배열을 갖고 있을 때, 각 배열에 소문자만큼의 노드를 갖고 추가해준다.
공간복잡도는 소문자의 길이 25 * 문자열의 길이만큼 추가되는 것 같다.
예제에서는 abc, apple, apk를 추가하는데, abc인 경우, 'a'를 만들고, 노드를 만들고, 'b'를 만들고, 노드를 만들고, 'c'를 만들고, 노드를 만든다. 마지막에는 isEnd로 해서 더 이상 검색할 내용을 알려준다.
따라서, 노드가 갖고 있는 정보는 Node[26] child 와 boolean isEnd 의 정보를 가져야 한다.
- Search : app를 검색하는 예제이다. apple이 이에 매칭이 되는데, Node.child['a'] -> Node.child['a'].child['p'] ->
Node.child['a'].child['p'].child['p']로 간다. search일 때는, isEnd 값을 확인하는데 apple은 Node.child['a'].child['p'].child['p'].child['l'].child['e']가 isEnd가 true 이므로, 해당 search 결과는 false가 return 된다.
- startWith : app을 검색하는 똑같은 예제일 때, startWith는 search와 동일 과정을 거치고, 마지막에 isEnd를 검사하지 않으므로, 무조건 return true를 한다.
5. 결과
'내 맘대로 알고리즘 > LeetCode 2020 May' 카테고리의 다른 글
May LeetCoding Challenge[Day16] - Odd Even Linked List (0) | 2020.05.21 |
---|---|
May LeetCoding Challenge[Day15] - Maximum Sum Circular Subarray (0) | 2020.05.20 |
May LeetCoding Challenge[Day13] - Remove K Digits (0) | 2020.05.18 |
May LeetCoding Challenge[Day12] - Single Element in a Sorted Array (0) | 2020.05.12 |
May LeetCoding Challenge[Day11] - Flood Fill (0) | 2020.05.12 |