
✅ 문제 설명
문제 이름: Implement Trie (Prefix Tree)
링크: LeetCode 208
✅ 문제 요구사항
- Trie라는 자료구조를 구현하세요.
-insert(word): 문자열word를 트라이에 삽입
-search(word):word가 정확히 존재하는지 반환 (true / false)
-startsWith(prefix):prefix로 시작하는 단어가 하나라도 존재하는지 반환
트라이는 문자열을 빠르게 저장하고 검색하기 위한 트리형 자료구조다.
단어를 문자 하나씩 잘라서 노드로 연결하고, 같은 접두사(prefix)를 공유하는 구조로 되어 있다.
주로 자동완성 기능 (ex: 검색창), 단어 사전 구현, 접두사 기반 검색, 문자열 집합에서 빠르게 찾기에 쓰인다.
apple을 저장하면root
└─ a
└─ p
└─ p
└─ l
└─ e (여기에 isEnd = true)
단어가 끝나는 마지막 글자에는 isEnd = true 표시를 붙여 "여기서 하나의 단어가 끝난다"는 걸 표시한다.
apple, app, apt를 저장하면root
└─ a
├─ p
│ ├─ p (끝 표시)
│ │ └─ l
│ │ └─ e (끝 표시)
└─ p
└─ t (끝 표시)
var Trie = function() {
this.root = {};
};
root는 트리의 시작점이다. 각 노드는 {} 형태의 객체이며, 알파벳을 키로 사용한다.
Trie.prototype.insert = function(word) {
let node = this.root;
for (let letter of word) {
if (node[letter] === undefined) node[letter] = {};
node = node[letter];
}
node.isEnd = true;
};
여기서 node는 지금 현재 글자를 삽입할 위치를 가리키는 포인터다. 매 글자마다 트리를 따라 내려가며, 없으면 새로 만들어주고 다음 글자로 이동한다.
insert("apple")의 수행 흐름이 과정을 마치고 나면 root는 이렇게 된다.
{
a: {
p: {
p: {
l: {
e: {
isEnd: true
}
}
}
}
}
}
Trie.prototype.search = function(word) {
let node = this.root;
for (let letter of word) {
if (!node[letter]) return false;
node = node[letter];
}
return node && node.isEnd === true;
};
"a" → "p" → "p" → "l" → "e" 한 글자씩 따라간다.
중간에 끊기면 false, 끝까지 가더라도 isEnd가 true여야 진짜 단어로 인정한다.
Trie.prototype.startsWith = function(prefix) {
let node = this.root;
for (let letter of prefix) {
if (!node[letter]) return false;
node = node[letter];
}
return true;
};
isEnd는 체크하지 않는다. 단어가 완성되지 않아도, 경로만 존재하면 true이다.
var Trie = function() {
this.root = {};
};
/**
* @param {string} word
* @return {void}
*/
Trie.prototype.insert = function(word) {
let node = this.root;
for(let letter of word) {
if (node[letter] === undefined) node[letter] = {};
node = node[letter];
}
node.isEnd = true;
};
/**
* @param {string} word
* @return {boolean}
*/
Trie.prototype.search = function(word) {
let node = this.root;
for(let letter of word) {
if(!node[letter]) return false;
node = node[letter];
}
return node && node.isEnd === true;
};
/**
* @param {string} prefix
* @return {boolean}
*/
Trie.prototype.startsWith = function(prefix) {
let node = this.root;
for(let letter of prefix) {
if(!node[letter]) {
return false;
} else {
node = node[letter];
}
}
return true;
};
/**
* Your Trie object will be instantiated and called as such:
* var obj = new Trie()
* obj.insert(word)
* var param_2 = obj.search(word)
* var param_3 = obj.startsWith(prefix)
*/