๐ ๋ฌธ์ ํ์ํ๊ธฐ
- N(2 ≤ N ≤ 20,000)๊ฐ์ ์๋จ์ด๋ค์ด ์ฃผ์ด์ง ๋ ๊ฐ์ฅ ๋น์ทํ ๋ ๋จ์ด ๊ตฌํ๊ธฐ
- ๋น์ทํ ์ ๋ = ๋๋จ์ด์ ์ ๋์ฌ ๊ธธ์ด๋ก ์ธก์
- ๋ ๋จ์ด์ ์์์๋ถํฐ M๊ฐ์ ๊ธ์๋ค์ด ๊ฐ์ ๋ M์ด ์ต๋์ธ ๊ฒฝ์ฐ ๊ตฌํ๊ธฐ
- ๊ทธ๋ฐ ๊ฒฝ์ฐ๊ฐ ์ฌ๋ฌ ๊ฐ์ผ ๊ฒฝ์ฐ ์ ๋ ฅ๋๋ ์์ผ๋ก ์ ์ผ ์์ ์๋ ๋จ์ด
- ์๋จ์ด๋ ์ํ๋ฒณ ์๋ฌธ์๋ก๋ง ์ด๋ฃจ์ด์ง๋ฉฐ, ๊ธธ์ด๋ 100์ ์ดํ
๋น์ทํ ์ ๋๋ฅผ ์ ๋์ฌ ๊ธธ์ด๋ก ์ธก์ ํ๋ค๋ ๊ฒ์ ๋ฐํ์ผ๋ก, ํธ๋ผ์ด ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๊ธฐ๋ก ํ๋ค. ํธ๋ผ์ด ์๋ฃ๊ตฌ์กฐ์ ๋จ์ด๋ฅผ ์์๋๋ก ์ ์ฅํ๋ฉด์, ํ์ฌ ๊ฐ์ฅ ๋น์ทํ ๋จ์ด๋ฅผ ๊ฐฑ์ ํด๋๊ฐ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํด์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด ๋ณด์๋ค.
๐ ์ฝ๋ ์ค๊ณํ๊ธฐ
class TrieNode
๊ตฌํ
- ํธ๋ผ์ด ์๋ฃ๊ตฌ์กฐ์ ๊ฐ ๋ ธ๋๋ฅผ ํํํ ํด๋์ค
- ํ๋กํผํฐ
children
: ๊ฐ ๋ ธ๋์ ํ์ ๋ ธ๋๋ฅผ ๋์ ๋๋ฆฌ ํํ๋ก ์ ์ฅis_end
: ๋ฌธ์์ด์ ๋ง์ง๋ง ๋ฌธ์์ธ์ง ์ฌ๋ถ๋ฅผ boolean ํํ๋ก ์ ์ฅfirst_prefix_idx
: ํด๋น ๋ ธ๋๊น์ง์ ๋ฌธ์์ด์ ์ ๋์ฌ๋ก ๊ฐ๋ ์ต์ด ๋จ์ด์ ์ธ๋ฑ์ค
class Trie
๊ตฌํ- ํ๋กํผํฐ
root
: ๋ฃจํธ ๋ ธ๋similar_words_idx
: ํธ๋ผ์ด์์ ๊ฐ์ฅ ๋น์ทํ ๋จ์ด ๋ ๊ฐ์ ์ธ๋ฑ์ค๋ฅผ ๋ฆฌ์คํธ๋ก ์ ์ฅsimilarity
: ํธ๋ผ์ด์์ ๊ฐ์ฅ ๋น์ทํ ๋จ์ด ๋ ๊ฐ์ ์ ์ฌ๋
- ๋ฉ์๋
insert(self, word, order)
:word
๋ฅผ ํธ๋ผ์ด์ ์๋ก ์ถ๊ฐํ๋ ๋ฉ์๋- ํ์ฌ ๋จ์ด์ ํธ๋ผ์ด ๊ฐ์ฒด ๋ด์ ๋ค๋ฅธ ๋จ์ด์ ๊ฐ์ฅ ๋์ ์ ์ฌ๋๋ฅผ ์ ์ฅํ
cur_similarity
๋ฅผ 0์ผ๋ก ์ด๊ธฐํํ๊ณ , ๊ทธ ๋จ์ด์ ๊ณตํต ์ ๋์ฌ์ ๋ง์ง๋ง ๋ ธ๋๋ฅผ ์ ์ฅํsimilar_node
๋ฅผself.root
๋ก ์ด๊ธฐํํ๋ค. word
๋ฅผ ๊ตฌ์ฑํ๋ ๋ฌธ์ ํ๋์ฉ ํ์ํ๋ฉฐ, ํ์ฌ ๋ ธ๋์ ํ์ ๋ ธ๋ ์ค ํด๋น ๋ฌธ์์ด์ ํค ๊ฐ์ผ๋ก ๊ฐ๋ ๋ ธ๋๊ฐ ์๋์ง ํ์ธ- ๋ง์ฝ 1์์ ํด๋น ๋ฌธ์์ด์ ํค ๊ฐ์ผ๋ก ๊ฐ๋ ๋
ธ๋๊ฐ ์๋ค๋ฉด, ์๋ก ์ถ๊ฐํด์ฃผ๋ฉด์ ํด๋น ๋
ธ๋์
first_prefix_idx
ํ๋กํผํฐ์order
(ํ์ฌword
์ ์์๋ฅผ ์ ์ฅ) - ๋ง์ฝ 2์์ ํด๋น ๋ฌธ์์ด์ ํค ๊ฐ์ผ๋ก ๊ฐ๋ ๋
ธ๋๊ฐ ์๋ค๋ฉด, ํด๋น ๋
ธ๋๊น์ง๋ฅผ ๊ณตํต ์ ๋์ฌ๋ก ๊ฐ๋ ๋จ์ด๊ฐ ์๋ค๋ ๊ฒ์ด๋ฏ๋ก ํ์ฌ ๋จ์ด์
cur_similarity
์ 1์ ๋ํ๊ณ ,similar_node
๋ฅผ ๊ทธ ๋ ธ๋๋ก ๊ฐฑ์ ํ๋ค. - ๋จ์ด ์ ์ฅ ์๋ฃ ํ, ๋ฌธ์ ์กฐ๊ฑด์ ๋ฐ๋ผ ํ์ฌ ๋จ์ด์ ์ ์ฌ๋๊ฐ ํธ๋ผ์ด์ ์ ์ฅ๋ ์ ์ฌ๋์ ๊ฐ์ผ๋ฉด, ์
๋ ฅ ์์(
first_prefix_idx
ํ์ฉ)๋ฅผ ๋น๊ตํด์self.similarity
์self.similar_words_idx
๋ฅผ ๊ฐฑ์ ํ๊ณ , ํ์ฌ ๋จ์ด์ ์ ์ฌ๋๊ฐ ํธ๋ผ์ด์ ์ ์ฅ๋ ์ ์ฌ๋๋ณด๋ค ๋์ผ๋ฉด ๋ฌด์กฐ๊ฑด ๊ฐฑ์ ํด์ค๋ค.
- ํ์ฌ ๋จ์ด์ ํธ๋ผ์ด ๊ฐ์ฒด ๋ด์ ๋ค๋ฅธ ๋จ์ด์ ๊ฐ์ฅ ๋์ ์ ์ฌ๋๋ฅผ ์ ์ฅํ
- ํ๋กํผํฐ
- ๋ฉ์ธ ๋ก์ง
- ๋จ์ด ๊ฐ์ N์ ์ ๋ ฅ๋ฐ๊ณ N๊ฐ์ ๋จ์ด๋ฅผ words ๋ฆฌ์คํธ์ ์ ์ฅํ๋ค.
- Trie์ ์ธ์คํด์ค trie๋ฅผ ์์ฑํ๊ณ , words์ ์์๋ฅผ ํ๋์ฉ trie.insertํ๋ค.
- trie.similar_words_idx๋ฅผ ๋ฐํ์ผ๋ก ๊ฐ์ฅ ์ ์ฌํ ๋จ์ด ๋ ๊ฐ๋ฅผ ์์๋๋ก ์ถ๋ ฅํ๋ค.
๐ ์ ๋ต ์ฝ๋
import sys
input = sys.stdin.readline
class TrieNode():
def __init__(self):
self.children = {}
self.is_end = False
self.first_prefix_idx = 0
class Trie():
def __init__(self):
self.root = TrieNode()
self.similar_words_idx = (0, 1)
self.similarity = 0
def insert(self, word, order):
node = self.root
similar_node = self.root
cur_similarity = 0
for char in word:
if char not in node.children:
node.children[char] = TrieNode()
node.children[char].first_prefix_idx = order
else:
cur_similarity += 1
similar_node = node.children[char]
node = node.children[char]
node.is_end = True
if (cur_similarity == self.similarity and self.similar_words_idx[0] > similar_node.first_prefix_idx) or cur_similarity > self.similarity:
self.similarity = cur_similarity
self.similar_words_idx = (similar_node.first_prefix_idx, order)
N = int(input())
words = [input().rstrip() for _ in range(N)]
trie = Trie()
for i in range(N):
trie.insert(words[i], i)
print(*(words[i] for i in trie.similar_words_idx), sep="\n")
728x90