ํธ๋ผ์ด(Trie)๋ ๋ฌธ์์ด์ ๋น ๋ฅด๊ฒ ๊ฒ์ํ ์ ์๋ ์๋ฃ ๊ตฌ์กฐ๋ก, ๋จ์ด ์ฌ์ ๊ณผ ๊ฐ์ ๊ฐ๋
์ด๋ผ๊ณ ๊ธฐ์ตํด๋๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค.
ํน์ ๋จ์ด๋ฅผ ์ฐพ๊ณ ์ถ์๋ฐ ๊ทธ ๊ฒ์ ์๊ฐ์ด ๋นจ๋์ผ๋ฉด ํ ๋, ์ฐ๋ฆฌ๋ ํธ๋ผ์ด(Trie) ๊ตฌ์กฐ๋ฅผ ๋ ์ฌ๋ ค๋ณด์.
๊ฒ์์ด ์๋ ์์ฑ, ์ฌ์ ์์ ์ฐพ๊ธฐ, ๋ฌธ์์ด ๊ฒ์ฌ ๋ฑ์์ ์ฌ์ฉํ ์ ์๋ค.
Prefix Tree, Digital Search Tree, Retrieval Tree ๋ผ๊ณ ๋ ๋ถ๋ฅธ๋ค.
- ๋ฌธ์์ด์ ์ ์ฅํ๊ณ ํจ์จ์ ์ผ๋ก ํ์ํ๊ธฐ ์ํ ํธ๋ฆฌ ํํ์ ์๋ฃ๊ตฌ์กฐ
- K์ง ํธ๋ฆฌ ๊ตฌ์กฐ
- ๋จ์ด ์ฌ์ ์ ํธ๋ผ์ด๋ก ์์ฑ, ๊ทธ ํ ์ฐพ์ ๋จ์ด๋ฅผ ํธ๋ผ์ด๋ฅผ ์ฌ์ฉํด ๊ฒ์
- ํธ๋ผ์ด์ root ๋ ธ๋๋ ํญ์ ๋น ๋ฌธ์์ด
์ ๊ทธ๋ฆผ์ ์ดํด๋ณด๋ฉด, ํธ๋ฆฌ์ ๊น์ด์ ๋ฐ๋ผ ๋จ์ด๋ฅผ 1๊ธ์, 2๊ธ์, 3๊ธ์์ฉ ์ ์ฅํ ๊ฒ์ ๋ณผ ์ ์๋ค. (root ๋ ธ๋๋ ๋น ๋ฌธ์์ด)
- 'tea' ์ฐพ๊ธฐ : ํธ๋ฆฌ๋ฅผ ๋ฐ๋ผ ๊ฐ์ t, e, a ๋ฅผ ์ฐพ๋๋ค.
- 'tee' ์ฐพ๊ธฐ : ํธ๋ฆฌ๋ฅผ ๋ฐ๋ผ ๊ฐ์ ๋ t, e ๋ค์ e๊ฐ ์๊ธฐ ๋๋ฌธ์ ์๋ ๊ธ์์ด๋ค.
- 'te' ์ฐพ๊ธฐ : t, e๊น์ง๋ ์์ง๋ง e๊ฐ ๋จ์ด์ ๋์ด ์๋๋ฏ๋ก ์๋ ๊ธ์์ด๋ค. (์ฆ ํธ๋ผ์ด์๋ ๋จ์ด์ ๋์ ์๋ฆฌ๋ flag๊ฐ ํ์ํ๋ค.)
์ ์ผ ๊ธด ๋จ์ด์ ๊ธธ์ด๋ฅผ M, ์ด ๋จ์ด๋ค์ ์๋ฅผ N์ด๋ผ๊ณ ํ ๋,
- ํธ๋ผ์ด ์์ฑ ์ ์๊ฐ ๋ณต์ก๋ : O(N *M) ๋จ์ด ํ๋๋ฅผ ์ฝ์ ํ๋๋ฐ ๊ฐ์ฅ ๊ธด ๋จ์ด์ ๊ธธ์ด M ๋งํผ ๊ฑธ๋ฆฌ๋ฏ๋ก O(M)์ด๊ณ , ์ด๋ฅผ N๊ฐ ๋ฃ์ผ๋ฏ๋ก O(N*M)์ด๋ค.
- ๋จ์ด ๊ฒ์ ์ ์๊ฐ ๋ณต์ก๋ : O(M) ๊ฐ์ฅ ๊ธด ๋ฌธ์์ด์ ๊ธธ์ด๋งํผ ๊ฑธ๋ฆฌ๋ฏ๋ก O(M)์ด๋ค.
๋จ์ด๋ฅผ ํ๋์ฉ ๋น๊ตํ๋ฉฐ ํ์ํ๋ ๊ฒ๋ณด๋ค ์๊ฐ์ ์ผ๋ก ํจ์ฌ ํจ์จ์ ์ด์ง๋ง,
๊ฐ ๋ ธ๋์์ ๊ทธ ์์ ๋ ธ๋์ ๋ํ ์ ๋ณด๋ฅผ ๋ฐฐ์ด๋ก ๊ฐ์ง๊ณ ์๊ณ , ๊ทธ ๋ ธ๋๋ค์ ๊ฐ์๋ฅผ ์๊ฐํด๋ดค์ ๋ ๊ณต๊ฐ ๋ณต์ก๋ ์ธก๋ฉด์์๋ ๋นํจ์จ์ ์ด๋ค.
ํธ๋ผ์ด ๋
ธ๋์ ํ์ํ ์ ๋ณด๋ ์์ ๋
ธ๋์ ๋ํ ์ ๋ณด children
, ํ์ฌ ๋
ธ๋๊ฐ ๋จ์ด์ ๋์ธ์ง ์ฌ๋ถ isEnd
์ด ๋ ๊ฐ์ง์ด๋ค.
์์ ์ฝ๋๋ ์ํ๋ฒณ ๋๋ฌธ์๋ง ์ ์ฅํ๋ ํธ๋ผ์ด๋ผ๊ณ ์๊ฐํ๊ณ ๊ตฌํํด๋ณด๊ฒ ๋ค.
๊ตฌํ์ ํธ์๋ฅผ ์ํด getChild, hasChild ๋ฉ์๋๋ ์ถ๊ฐํด์ค๋ค.
class TrieNode {
TrieNode[] children = new TrieNode[26]; // ์ํ๋ฒณ ๋๋ฌธ์๋ง
boolean isEnd;
TrieNode getChild(char c) {
return children[c - 'A'];
}
boolean hasChild(char c) {
return children[c - 'A'] != null;
}
}
๋จ์ด ์ฌ์ ์ ๋จ์ด๋ฅผ ํธ๋ผ์ด์ ํ๋์ฉ ์ฝ์ ํ๋ค๊ณ ์๊ฐํด๋ณด์.
- ๋ฃจํธ ๋ ธ๋๋ถํฐ ์์ํ์ฌ ๋จ์ด์ ์ฒซ ๊ธ์๋ถํฐ ํธ๋ผ์ด๋ฅผ ํ์ํ๋ค.
- ํ์ฌ ๋ ธ๋์ ์์ ๋ ธ๋ ์ค ํ์ฌ ํ์ ์ค์ธ ๋ฌธ์๊ฐ ์๋ค๋ฉด, ๊ทธ ์์ ๋ ธ๋๋ก ์ด๋ํ๋ค.
- ํ์ฌ ๋ ธ๋์ ์์ ๋ ธ๋ ์ค ํ์ฌ ํ์ ์ค์ธ ๋ฌธ์๊ฐ ์๋ค๋ฉด, ์๋ก์ด ์์ ๋ ธ๋๋ฅผ ์ถ๊ฐํ๋ค.
- ๋จ์ด์ ๋ง์ง๋ง ๊ธ์๊น์ง ์๋ค๋ฉด, isEnd๋ฅผ true๋ก ํด์ฃผ๋ฉด ๋จ์ด์ ๋ํ ์ ๋ณด๊ฐ ํธ๋ผ์ด์ ์ ์ฅ๋๋ค.
- ๋ฃจํธ ๋ ธ๋๋ถํฐ ์์ํ์ฌ ๋จ์ด์ ์ฒซ ๊ธ์๋ถํฐ ํธ๋ผ์ด๋ฅผ ํ์ํ๋ค.
- ํ์ฌ ๋ ธ๋์ ์์ ๋ ธ๋ ์ค ํ์ฌ ํ์ ์ค์ธ ๋ฌธ์๊ฐ ์๋ค๋ฉด, ๊ทธ ์์ ๋ ธ๋๋ก ์ด๋ํ๋ค.
- ํ์ฌ ๋
ธ๋์ ์์ ๋
ธ๋ ์ค ํ์ฌ ํ์ ์ค์ธ ๋ฌธ์๊ฐ ์๋ค๋ฉด,
return false
- ๋จ์ด์ ๋ง์ง๋ง ๊ธ์๊น์ง ์๋๋ฐ, isEnd๊ฐ false๋ผ๋ฉด
return false
- ๋จ์ด์ ๋ง์ง๋ง ๊ธ์๊น์ง ์๊ณ , isEnd๊ฐ true๋ผ๋ฉด
return true
ํธ๋ผ์ด ์์ฑ, ๊ฒ์์ ๊ดํ Trie ํด๋์ค๋ฅผ ๊ตฌํํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
class Trie {
TrieNode root = new TrieNode(); // ๋ฃจํธ ๋
ธ๋ ์์ฑ
void insert(String word) {
TrieNode current = root;
for (int i = 0; i < word.length(); i++) { // ๋จ์ด์ ์ฒซ ๊ธ์ ~ ๋ ๊ธ์๊น์ง ํ์
char c = word.charAt(i);
if (!current.hasChild(c)) { // ํด๋น ๋ฌธ์์ ๋ํ ์์ ๋
ธ๋ ์๋์ง ๊ฒ์ ํ ๊ทธ ์์ ๋
ธ๋๋ก ์ด๋
current.children[c - 'A'] = new TrieNode();
}
current = current.getChild(c);
}
current.isEnd = true; // ๋ ๊ธ์์์ ์๋ฆฌ๋ ํ๋๊ทธ ์ ์ฉ
}
boolean checkWord(String word) {
TrieNode current = root;
for (int i = 0; i < word.length(); i++) { // ๋จ์ด์ ์ฒซ ๊ธ์ ~ ๋ ๊ธ์๊น์ง ํ์
char c = word.charAt(i);
if (current.hasChild(c)) { // ํด๋น ๋ฌธ์์ ๋ํ ์์ ๋
ธ๋ ์๋ค๋ฉด ๊ทธ ์์ ๋
ธ๋๋ก ์ด๋
current = current.getChild(c);
} else { // ํด๋น ๋ฌธ์์ ๋ํ ์์ ๋
ธ๋ ์์ผ๋ฉด return false
return false;
}
}
return current.isEnd; // ๋๊น์ง ์๋๋ฐ isEnd๋ผ๋ฉด true, ์๋๋ฉด false
}
}
์์ ์ฝ๋ ๋ฐ๋ก ๊ฐ๊ธฐ