-
Notifications
You must be signed in to change notification settings - Fork 126
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5a677bd
commit 1a8ba73
Showing
1 changed file
with
115 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/** | ||
* @problem | ||
* Trieλ₯Ό ꡬνν©λλ€. | ||
* - λ©λͺ¨λ¦¬ μ¬μ©λμ μ΅μ ννλ©΄μ μ νν κ²μ κ²°κ³Όλ₯Ό 보μ₯ν΄μΌ ν©λλ€. | ||
* | ||
* @example | ||
* const trie = new Trie(); | ||
* trie.insert("apple"); // undefined | ||
* trie.search("apple"); // true | ||
* trie.search("app"); // false | ||
* trie.startsWith("app"); // true | ||
* trie.insert("app"); // undefined | ||
* trie.search("app"); // true | ||
* | ||
* @description | ||
* - μκ°λ³΅μ‘λ: | ||
* γ΄ insert: O(m) (mμ λ¨μ΄ κΈΈμ΄) | ||
* γ΄ search: O(m) (mμ λ¨μ΄ κΈΈμ΄) | ||
* γ΄ startsWith: O(m) (mμ μ λμ¬ κΈΈμ΄) | ||
* - 곡κ°λ³΅μ‘λ: O(ALPHABET_SIZE * m * n) | ||
* γ΄ ALPHABET_SIZE: λ¬Έμμ΄μ μνλ²³ μ (μλ¬Έμ κ²½μ° 26) | ||
* γ΄ m: λ¨μ΄μ νκ· κΈΈμ΄ | ||
*/ | ||
class TrieNode { | ||
constructor() { | ||
// κ° λ¬Έμλ₯Ό ν€λ‘ νκ³ μμ λ Έλλ₯Ό κ°μΌλ‘ νλ κ°μ²΄ | ||
this.children = {}; | ||
// νμ¬ λ Έλκ° λ¨μ΄μ λ§μ§λ§ λ¬ΈμμΈμ§ νμνλ νλκ·Έ | ||
this.isEndOfWord = false; | ||
} | ||
} | ||
|
||
class Trie { | ||
constructor() { | ||
// λΉ λ¬Έμμ΄μ λνλ΄λ λ£¨νΈ λ Έλ μμ± | ||
this.root = new TrieNode(); | ||
} | ||
|
||
/** | ||
* λ¨μ΄λ₯Ό Trieμ μ½μ νλ λ©μλ | ||
* @param {string} word - μ½μ ν λ¨μ΄ | ||
*/ | ||
insert(word) { | ||
// λ£¨νΈ λ ΈλλΆν° μμ | ||
let node = this.root; | ||
|
||
// λ¨μ΄μ κ° λ¬Έμλ₯Ό μν | ||
for (let i = 0; i < word.length; i++) { | ||
const char = word[i]; | ||
// νμ¬ λ¬Έμμ λν λ Έλκ° μμΌλ©΄ μλ‘ μμ± | ||
if (!(char in node.children)) { | ||
node.children[char] = new TrieNode(); | ||
} | ||
// λ€μ λ¬Έμλ₯Ό μ²λ¦¬νκΈ° μν΄ μμ λ Έλλ‘ μ΄λ | ||
node = node.children[char]; | ||
} | ||
// λ¨μ΄μ λ§μ§λ§ λ¬Έμμμ νμ | ||
node.isEndOfWord = true; | ||
} | ||
|
||
|
||
/** | ||
* μ νν λ¨μ΄κ° μ‘΄μ¬νλμ§ κ²μνλ λ©μλ | ||
* @param {string} word - κ²μν λ¨μ΄ | ||
* @returns {boolean} - λ¨μ΄ μ‘΄μ¬ μ¬λΆ | ||
*/ | ||
search(word) { | ||
// λ¨μ΄λ₯Ό μ°Ύμ λ§μ§λ§ λ Έλλ₯Ό λ°ν | ||
const node = this._traverse(word); | ||
// λ¨μ΄κ° μ‘΄μ¬νκ³ ν΄λΉ λ Έλκ° λ¨μ΄μ λμΈ κ²½μ°μλ§ true λ°ν | ||
return node !== null && node.isEndOfWord; | ||
} | ||
|
||
/** | ||
* μ£Όμ΄μ§ μ λμ¬λ‘ μμνλ λ¨μ΄κ° μ‘΄μ¬νλμ§ κ²μνλ λ©μλ | ||
* @param {string} prefix - κ²μν μ λμ¬ | ||
* @returns {boolean} - μ λμ¬λ‘ μμνλ λ¨μ΄ μ‘΄μ¬ μ¬λΆ | ||
*/ | ||
startsWith(prefix) { | ||
// μ λμ¬μ ν΄λΉνλ λ Έλκ° μ‘΄μ¬νλμ§λ§ νμΈ | ||
return this._traverse(prefix) !== null; | ||
} | ||
|
||
/** | ||
* λ¬Έμμ΄μ λ°λΌκ°λ©° λ§μ§λ§ λ Έλλ₯Ό λ°ννλ λ΄λΆ ν¬νΌ λ©μλ | ||
* @param {string} str - νμν λ¬Έμμ΄ | ||
* @returns {TrieNode|null} - λ§μ§λ§ λ¬Έμμ ν΄λΉνλ λ Έλ λλ null | ||
* @private | ||
*/ | ||
_traverse(str) { | ||
// λ£¨νΈ λ ΈλλΆν° μμ | ||
let node = this.root; | ||
|
||
// λ¬Έμμ΄μ κ° λ¬Έμλ₯Ό μν | ||
for (let i = 0; i < str.length; i++) { | ||
const char = str[i]; | ||
// νμ¬ λ¬Έμμ λν λ Έλκ° μμΌλ©΄ null λ°ν | ||
if (!(char in node.children)) { | ||
return null; | ||
} | ||
// λ€μ λ¬Έμλ₯Ό μ²λ¦¬νκΈ° μν΄ μμ λ Έλλ‘ μ΄λ | ||
node = node.children[char]; | ||
} | ||
// λ§μ§λ§ λ Έλ λ°ν | ||
return node; | ||
} | ||
} | ||
|
||
const trie = new Trie(); | ||
console.log(trie.insert("apple")); // undefined | ||
console.log(trie.search("apple")); // true | ||
console.log(trie.search("app")); // false | ||
console.log(trie.startsWith("app")); // true | ||
console.log(trie.insert("app")); // undefined | ||
console.log(trie.search("app")); // true |