|
| 1 | +# ํด์ |
| 2 | +# 0. TrieNode ํด๋์ค ์ ์: |
| 3 | +# - ๊ฐ TrieNode ์ธ์คํด์ค๋ ๋ค์์ ๋ ๊ฐ์ง ์์ฑ์ ๊ฐ์ง๋ค: |
| 4 | +# 1) children: ํ์ฌ ๋
ธ๋์ ์์ ๋
ธ๋๋ค์ ์ ์ฅํ๋ ๋์
๋๋ฆฌ (๋ฌธ์ -> TrieNode ์ธ์คํด์ค). |
| 5 | +# 2) is_end_of_word: ํ์ฌ ๋
ธ๋๊ฐ ๋จ์ด์ ๋์ธ์ง ๋ํ๋ด๋ Boolean ๊ฐ. |
| 6 | + |
| 7 | +# 1. WordDictionary ํด๋์ค ์ ์: |
| 8 | +# - WordDictionary ํด๋์ค๋ Trie ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋จ์ด๋ฅผ ์ ์ฅ(addWord)ํ๊ณ ํ์(search)ํ๋ค. |
| 9 | + |
| 10 | +# 1-1. __init__ ํจ์: |
| 11 | +# - root๋ TrieNode ํด๋์ค๋ก ์์ฑ๋ ์ธ์คํด์ค๋ฅผ ๊ฐ์ง๋ค. |
| 12 | +# - Trie ์๋ฃ๊ตฌ์กฐ์ ์์์ (๋ฃจํธ ๋
ธ๋) ์ญํ ์ ํ๋ค. |
| 13 | + |
| 14 | +# 1-2. addWord ํจ์: |
| 15 | +# 1) ๋ฃจํธ ๋
ธ๋(self.root)์์ ์์. |
| 16 | +# 2) ๋จ์ด์ ๊ฐ ๋ฌธ์๋ฅผ ์ํํ๋ฉฐ: |
| 17 | +# - ํ์ฌ ๋
ธ๋์ children์ ๋ฌธ์๊ฐ ์์ผ๋ฉด, ์ TrieNode๋ฅผ ์์ฑํด ์ถ๊ฐ. |
| 18 | +# - ํ์ฌ ๋
ธ๋๋ฅผ ํด๋น ๋ฌธ์์ ์์ ๋
ธ๋๋ก ์ด๋. |
| 19 | +# 3) ๋จ์ด์ ๋ง์ง๋ง ๋ฌธ์๋ฅผ ์ฒ๋ฆฌํ ํ, ํด๋น ๋
ธ๋์ is_end_of_word๋ฅผ True๋ก ์ค์ . |
| 20 | + |
| 21 | + |
| 22 | +# 1-3. search ํจ์: |
| 23 | +# - ์ฃผ์ด์ง ๋จ์ด๊ฐ Trie์ ์กด์ฌํ๋์ง ํ์ธํ๋ ํจ์. |
| 24 | +# - ์์ผ๋์นด๋ ๋ฌธ์(.)๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค. |
| 25 | +# - ๋ด๋ถ์ ์ผ๋ก dfs(๊น์ด ์ฐ์ ํ์) ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ํธ๋ผ์ด๋ฅผ ํ์. |
| 26 | +# - dfs(index, node): |
| 27 | +# 1) ์ข
๋ฃ ์กฐ๊ฑด: index๊ฐ ๋จ์ด ๊ธธ์ด์ ๋๋ฌํ๋ฉด, ํ์ฌ ๋
ธ๋์ is_end_of_word ๋ฐํ. |
| 28 | +# 2) ํ์ฌ ๋ฌธ์๊ฐ '.'์ธ ๊ฒฝ์ฐ: |
| 29 | +# - ํ์ฌ ๋
ธ๋์ ๋ชจ๋ ์์ ๋
ธ๋์ ๋ํด dfs๋ฅผ ํธ์ถ. |
| 30 | +# - ํ๋๋ผ๋ True๋ฅผ ๋ฐํํ๋ฉด True ๋ฐํ. |
| 31 | +# 3) ํ์ฌ ๋ฌธ์๊ฐ ์ผ๋ฐ ๋ฌธ์์ธ ๊ฒฝ์ฐ: |
| 32 | +# - ์์ ๋
ธ๋์ ๋ฌธ์๊ฐ ์์ผ๋ฉด False ๋ฐํ. |
| 33 | +# - ์์ ๋
ธ๋๋ก ์ด๋ํด dfs๋ฅผ ์ฌ๊ท ํธ์ถ. |
| 34 | + |
| 35 | + |
| 36 | + |
| 37 | + #Big O |
| 38 | + # - N: ์ ์ฅ๋ ๋ชจ๋ ๋จ์ด์ ์ด ๋ฌธ์ ์ (Trie์ ์ ์ฅ๋ ๋ชจ๋ ๋ฌธ์์ ๊ฐ์). |
| 39 | + # - C: ์ํ๋ฒณ์ ๊ฐ์ (์์ด ๊ธฐ์ค ์ต๋ 26). |
| 40 | + |
| 41 | + #Time Complexity: O(N) |
| 42 | + #- addWordํจ์ : N์ ๊ธฐ๋ฐํ์ฌ ๋จ์ด ์ถ๊ฐ |
| 43 | + #- searchWord ํจ์: |
| 44 | + # - ์ผ๋ฐ ํ์: O(n), n์ ๋จ์ด์ ๊ธธ์ด. |
| 45 | + # - ์์ผ๋์นด๋ ํ์: ์ต์
์ ๊ฒฝ์ฐ O(C^N), |
| 46 | + # - C๋ ์ํ๋ฒณ ๊ฐ์ (์ต๋ 26). |
| 47 | + # - N์ ๋จ์ด์ ๊ธธ์ด. ์์ผ๋์นด๋ ๋ฌธ์๊ฐ ๋ง์์๋ก ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ํ์ํด์ผ ํ ์๋ ์์. |
| 48 | + |
| 49 | + # - Space Complexity: O(N ร C) |
| 50 | + # |
| 51 | + # - ๊ฐ ๋
ธ๋๋: |
| 52 | + # 1) children ๋์
๋๋ฆฌ๋ฅผ ํตํด ์์ ๋
ธ๋๋ฅผ ์ ์ฅ (๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ). |
| 53 | + # 2) is_end_of_word ๋ณ์ (Boolean ๊ฐ, O(1)). |
| 54 | + # - Trie์ ์ ์ฅ๋ ๋จ์ด์ ๋ฌธ์ ์๊ฐ ๋ง์์๋ก ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ฆ๊ฐ. |
| 55 | + |
| 56 | +class TrieNode: |
| 57 | + def __init__(self): |
| 58 | + self.children = {} #์ํ๋ฒณ a๋ถํฐ z๊น์ง๋ฅผ ์์์ผ๋ก ๊ฐ์ง, ํฌ๊ธฐ 26์ ๋ฐฐ์ด์ด๋ ๋์
๋๋ฆฌ๋ฅผ ์ฌ์ฉ. |
| 59 | + self.is_end_of_word = False #์ด๋ค ๋จ์ด์ ๋์ธ์ง ๋ํ๋ด๋ Boolean ๊ฐ |
| 60 | + #์๋ฅผ ๋ค์ด, "note"์ด๋ผ๋ ๋จ์ด์ 'e'์ ํด๋นํ๋ ๋
ธ๋์ is_end_of_word๊ฐ True, 'n' |
| 61 | + |
| 62 | +class WordDictionary: |
| 63 | + def __init__(self): |
| 64 | + self.root = TrieNode() # WD๋ก ์์ฑ๋ ์ธ์คํด์ค.root = TrieNode ์ธ์คํด์ค |
| 65 | + |
| 66 | + def addWord(self, word: str) -> None: |
| 67 | + node = self.root #node์ self.root๋ฅผ ๋ถ์ฌ |
| 68 | + for char in word: # ๋งค๊ฐ๋ณ์ word๋ฅผ ํ๋์ฉ ์ํํ๋ฉฐ char์ ์ ์ฅ (์: word="note" -> char="n", "o", "t", "e") |
| 69 | + if char not in node.children: # ๋ง์ฝ char๊ฐ ํ์ฌ ๋
ธ๋์ ์์ ๋
ธ๋ ๋ชฉ๋ก์ ์๋ค๋ฉด |
| 70 | + node.children[char] = TrieNode() |
| 71 | + #node.children[char]์ TrideNode ์ธ์คํด์ค๋ก ์์ฑ |
| 72 | + # self.root.children = { |
| 73 | + # "n": TrieNode() # "n" ํค๊ฐ ์ถ๊ฐ๋๊ณ , ๊ฐ์ผ๋ก ์๋ก์ด TrieNode ์ธ์คํด์ค๊ฐ ๋ค์ด๊ฐ |
| 74 | + # } |
| 75 | + |
| 76 | + #Example1: |
| 77 | + #root |
| 78 | + #โโโ "n" (children={}, is_end_of_word=False) |
| 79 | + |
| 80 | + #Example2: |
| 81 | + #โโโ "n" (children={}, is_end_of_word=False) |
| 82 | + # โโโ "o" (children={}, is_end_of_word=False) |
| 83 | + node = node.children[char] #node๋ฅผ ํ node์ children[char]๋ก ์ด๋ |
| 84 | + #Example1: |
| 85 | + # node = node.children["n"] |
| 86 | + |
| 87 | + #Example2: |
| 88 | + # node = node.children["o"] |
| 89 | + node.is_end_of_word = True |
| 90 | + #After for loop, ๋ ๋
ธ๋์ is_end_of_word๋ฅผ True๋ก ์ ํ |
| 91 | + |
| 92 | + #Example 4: |
| 93 | + #root |
| 94 | + #โโโ "n" |
| 95 | + #โโโ "o" |
| 96 | + #โโโ "t" |
| 97 | + #โโโ "e" (children={}, is_end_of_word=True) |
| 98 | + |
| 99 | + def search(self, word: str) -> bool: |
| 100 | + def dfs(index, node): # DFS ํจ์ ์ ์ |
| 101 | + # 1) ์ข
๋ฃ ์กฐ๊ฑด: ๋ชจ๋ ๋ฌธ์๋ฅผ ํ์ํ ๊ฒฝ์ฐ |
| 102 | + if index == len(word): |
| 103 | + return node.is_end_of_word # ๋จ์ด ๋ ์ฌ๋ถ ๋ฐํ |
| 104 | + # 2) ํ์ฌ ๋ฌธ์ ์ฒ๋ฆฌ |
| 105 | + char = word[index] |
| 106 | + if char == '.': # 2-1) ์์ผ๋์นด๋์ธ ๊ฒฝ์ฐ |
| 107 | + for child in node.children.values(): # ๋ชจ๋ ์์ ๋
ธ๋ ํ์ |
| 108 | + if dfs(index + 1, child): #dfs๋ฅผ ์ฌ๊ทํธ์ถ ํ์ฌ ๋ค์ ๋
ธ๋๋ก ํ์ ์ฌ๊ฐ |
| 109 | + return True #์ฌ๊ท ์ดํ์ ์์ผ๋ฉด True |
| 110 | + return False #์์ผ๋ฉด False |
| 111 | + else: # 2-2) ์ผ๋ฐ ๋ฌธ์ ์ฒ๋ฆฌ |
| 112 | + if char not in node.children: # ํ์ฌ ๋ฌธ์๊ฐ ์์ ๋
ธ๋์ ์๋ ๊ฒฝ์ฐ False |
| 113 | + return False |
| 114 | + return dfs(index + 1, node.children[char]) # ๋ค์ ๋
ธ๋๋ก ์ด๋ํ์ฌ ํ์ |
| 115 | + |
| 116 | + return dfs(0, self.root) |
| 117 | + #1. def dfs๋ฅผ self.root ์์น์์ ์ฒซ ํธ์ถ. |
| 118 | + |
| 119 | + |
| 120 | + |
| 121 | + |
0 commit comments