[Leetcode] 211. Design Add and Search Words Data Structure
๋จ์ด ๋ฑ๋ก๊ณผ ๋จ์ด ๊ฒ์์ ํ ์ ์๋ ์๋ฃ๊ตฌ์กฐ๋ฅผ ๋ง๋๋ ๋ฌธ์ ๋ค.
์์ฑ์์ ์๋ฃ๊ตฌ์กฐ๋ฅผ word๋ฅผ ๋ฑ๋กํ๋addWord(word)
ํจ์, ์๋ฃ๊ตฌ์กฐ์์ word๋ฅผ ๊ฒ์ํ๋ searchWord(word)
ํจ์๋ฅผ ์์ฑํด์ผ ํ๋ค.
๊ฒ์ ํจ์์์ word๋ ์ (.
)์ ์ต๋ 2๊ฐ๊น์ง ํฌํจํ ์ ์์ผ๋ฉฐ ์ ์ ๋ชจ๋ ๋ฌธ์๋ฅผ ๋์ฒดํ ์ ์๋ค.
์๋ฅผ๋ค์ด bad๋ผ๋ ๋จ์ด๊ฐ ์๋ฃ๊ตฌ์กฐ์ ์กด์ฌํ ๋ ..d๋ฅผ ๊ฒ์ํ๋ฉด True
๋ฅผ ๋ฐํํ๋ค.
์ฒ์ ๋ฌธ์ ๋ฅผ ์ ํ์ ๋ ๋จ์ํ ๋ฆฌ์คํธ๋ฅผ ๋ง๋ค๊ณ ์ฒซ๊ธ์๋ก ํ๋ณด๊ตฐ์ ์ค์ธ ํ ==์ฐ์ฐ์ ํตํด ๋จ์ด๋ฅผ ๋น๊ตํ๋ ค๊ณ ํ๋ค.
ํ์ง๋ง word์ ๋ชจ๋ ๋ฌธ์๋ฅผ ๋์ฒดํ ์ ์๋ .
์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ์ผ์ผ์ด ๋น๊ตํด์ผ ํ๊ณ , ์ด ๋ฐฉ์์ ํฐ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๋ค๋ ๊ฒ์ ์๊ณ ๊ทธ๋ง๋๋ค.
๊ทธ๋ฌ๋ค Trie๋ผ๋ ์๋ฃ๊ตฌ์กฐ๋ฅผ ๋ฐ๊ฒฌํ๋ค.
Trie
๋ ๋ฌธ์์ด์ ์ ์ฅํ๊ณ ํจ์จ์ ์ผ๋ก ํ์ํ๊ธฐ ์ํ Tree
ํํ์ ์๋ฃ๊ตฌ์กฐ๋ค.
์ ๊ทธ๋ฆผ์ POT, PAST, PASS, PART๋ฅผ ์ ์ฅํ Trie
๋ค.
์๋ฅผ๋ค์ด PART๋ฅผ ๊ฒ์ํ๋ค๊ณ ํ๋ฉด P, A, R, T ์์๋ก ๊ฒ์ํ๊ฒ ๋๋ค.
์ด ๋ P, A, R ๋
ธ๋๋ฅผ ๊ฑฐ์น๋ฉฐ ํ์ ํ๋ณด๊ตฐ์ ์ค์ด๊ฒ ๋๊ณ ์ด๋ก์ธํด ๋จ์ด๋ฅผ ์ผ์ผ์ด ๋น๊ตํ๋ ๊ฒ ๋ณด๋ค ์๊ฐ๋ณต์ก๋ ์ธก๋ฉด์์ ๋ ํจ์จ์ ์ด๋ค.
Node
class Node(object):
def __init__(self, key, data=None):
self.key = key
self.data = data
self.children = {}
๋ ธ๋๋ ๋ค์๊ณผ ๊ฐ์ ์ ๋ณด๋ค์ ๊ฐ์ง๋ค.
key
.data
. ํด๋น ๊ฐ์ผ๋ก ๋ฌธ์์ด์ด ์ข
๋ฃ๋จ์ ์ ์ ์๋ค.children
.Trie
์์ฑ์
def __init__(self):
self.head = Node(None)
key
๊ฐ์ ๊ฐ์ง์ง ์๋ head ๋
ธ๋๋ฅผ ์์ฑํ๋ค.addword
def addWord(self, word: str) -> None:
curr = self.head
for char in word:
if char not in curr.children:
curr.children[char] = Node(char)
curr = curr.children[char]
curr.data = word
curr
๊ฐ์ head๋ก ์ค์ ํด head ๋
ธ๋๋ถํฐ ํ์ ์์ํ๋ค.curr
์ children
์ ์กด์ฌํ์ง ์๋๋ค๋ฉด ํด๋น ๋ฌธ์๋ฅผ key
๊ฐ์ผ๋ก ๊ฐ๋ ๋
ธ๋๋ฅผ ์์ฑ ํ children
์ ์ถ๊ฐํ๋ฉฐ ํ๋์ฉ ๊ฒ์ฌํ๋ค.data
๊ฐ์ ํด๋น ๋ฌธ์์ด์ ์ ์ฅํ๋ค.search
def search(self, word: str) -> bool:
curr = self.head
for char in word:
if char in curr.children:
curr = curr.children[char]
else:
return False
if curr.data:
return True
else:
return False
curr
๊ฐ์ head๋ก ์ค์ ํด head ๋
ธ๋๋ถํฐ ํ์ ์์ํ๋ค.children
์ ์กด์ฌํ๋์ง ๊ฒ์ฌํ๋ค. ์ค๊ฐ์ ์กด์ฌํ์ง ์๋๋ค๋ฉด False
๋ฅผ ๋ฐํ.data
๊ฐ์ด ์กด์ฌํ๋ค๋ฉด True
, ๊ทธ๋ ์ง ์์ผ๋ฉด False
๋ฅผ ๋ฐํํ๋ค.data
๊ฐ์ด ํ์ํ ์ด์ : ์ฌ์ ์ FARM์ด๋ผ๋ ๋จ์ด๊ฐ ์กด์ฌํ๋ค๊ณ ๊ฐ์ ํ ๋ FAR๋ฅผ ๊ฒ์ํ ๊ฒฐ๊ณผ๋ False
์ด์ด์ผ ํ๊ธฐ ๋๋ฌธ.ํด๋น Trie์ ๋ชจ๋ ๋ฌธ์๋ฅผ ๋์ฒดํ ์ ์๋ .
์ด๋ผ๋ ๋ฌธ์ ์ ์กฐ๊ฑด์ ์ถ๊ฐํ๊ธฐ ์ํด์ search ํจ์๋ง ์์ ํ๋ฉด ๋๋ค.
์์ ๋ search()
def search(self, word: str, curr=None) -> bool:
if not curr:
curr = self.head
for i in range(len(word)):
char = word[i]
if char == '.':
for c in curr.children:
if self.search(word[i+1:], curr.children[c]):
return True
return False
elif char in curr.children:
curr = curr.children[char]
else:
return False
if curr.data:
return True
else:
return False
.
๋ฅผ ๋ง๋๋ค๋ฉด ํด๋น ๋
ธ๋์ ๋ชจ๋ children
๊ฐ์ ๋ํด serch ํจ์๋ฅผ ์ฌ๊ท ์คํํ๋ค. ์ด๋ ํ์์ค์ธ ๋
ธ๋์ ์์น๋ฅผ ์ ์ฅํ๊ธฐ ์ํด ๋งค๊ฐ๋ณ์ curr
๋ฅผ ๋ง๋ค์๋ค.
ํต๊ณผ๋ ํ์ง๋ง ์ข ๋๋ฆฌ๋ค.
leetcode์ ์ฝ๋ ์ํ์ ๋๋ฌ๋ณด๋ค ๋์
๋๋ฆฌ๋ฅผ ํ์ฉํ ์ฝ๋๋ฅผ ๋ฐ๊ฒฌํด ๊ฐ์ ธ์๋ดค๋ค.
๋์
๋๋ฆฌ๋ฅผ ์ธ ์๊ฐ์ ํด๋ดค์ง๋ง .
์ ์กด์ฌ๋๋ฌธ์ ์ฒซ๊ธ์๋ฅผ key๋ก ์ฌ์ฉํ ์ ์์ ๊ฒ ๊ฐ์ ํฌ๊ธฐํ์๋๋ฐ ์ด ์ฝ๋์๋ ๋ฌธ์์ด์ ๊ธธ์ด๋ฅผ key๋ก ์ฌ์ฉํ๋ค.
์์ฑ์
def __init__(self):
self.trie = defaultdict(set)
self.visited = dict()
trie
์ visited
๋๊ฐ์ ๋์
๋๋ฆฌ๋ฅผ ๊ฐ์ง๋ค. trie
๋ ๋ฌธ์์ด์ ์ ์ฅํ๊ธฐ ์ํ ๋์
๋๋ฆฌ, visited
๋ ์ด์ ์ ๊ฒ์ํ ๋ฌธ์์ด์ ๋ํ ๊ฒ์๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํด ๋๊ฐ์ ๋ฌธ์์ด์ ๊ฒ์ํ์ ๋ ๊ฒ์ ๊ณผ์ ์ ์๋ตํด์ค๋ค.addWord
def addWord(self, word: str) -> None:
self.trie[len(word)].add(word)
trie
์ ๋ฌธ์์ด์ ๊ธธ์ด๋ฅผ key๊ฐ, ๋ฌธ์์ด์ value๊ฐ์ผ๋ก ์ถ๊ฐํ๋ค.search
def search(self, word: str) -> bool:
N = len(word)
key = (word, len(self.trie[N]))
if key in self.visited:
return self.visited[key]
for candidate in self.trie[N]:
i, j = 0, 0
is_found = True
# both length are supposed to be equal
while i < len(candidate) and j < len(word):
if candidate[i] != word[j] and word[j] != ".":
is_found = False
break
i += 1
j += 1
if is_found:
self.visited[key] = True
return True
self.visited[key] = False
return False
visited
์ ์กด์ฌํ๋ค๋ฉด, ์ฆ ์ด์ ๊ฒ ๊ฒ์ํ ๊ธฐ๋ก์ด ์๋ค๋ฉด ์ ์ฅํ๋ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐํํ๋ค.trie
๋ด์์ word์ ๊ธธ์ด๊ฐ key ๊ฐ์ธ ๋ฌธ์์ด๋ค์ด ํ๋ณด๊ตฐ์ด ๋๋ค.visited
๋ฅผ ์
๋ฐ์ดํธํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค.์ฒ์์ ์๊ฐํ ํ๋ํ๋ ๋น๊ตํ๋ ๋ฐฉ์๊ณผ ์ ์ฌํ์ง๋ง ๋ฌธ์์ด์ ์ฒซ๊ธ์๋ฅผ key๋ก ๊ฐ์ ธ์ผํ๋ค๋ ์๊ฐ์ ์ฌ๋ก์กํ ๋ ์ฌ๋ฆฌ์ง ๋ชปํ๋ฐฉ๋ฒ์ด๋ค.
์ถ๊ฐ๋ก ์ด์ ์ ๊ฒ์ํ๋ ๋ฌธ์์ด์ ์ ์ฅํด ์ค๋ณต ํ์์ ๋ฐฉ์งํด ์ข ๋ ํจ์จ์ ์ด๋ค.
ํ์ง๋ง ๊ฐ์ ๊ธธ์ด์ธ ๋ฌธ์์ด์ด ๋ง์ ๊ฒฝ์ฐ ํจ์จ์ฑ์ด ๋จ์ด์ง๋ ๋ฐฉ๋ฒ์ธ ๊ฒ ๊ฐ๋ค.