|
| 1 | +class TrieNode: |
| 2 | + def __init__(self): |
| 3 | + self.children = {} |
| 4 | + self.isEndOfWord = False |
| 5 | + |
| 6 | +class Trie: |
| 7 | + def __init__(self): |
| 8 | + self.root = TrieNode() |
| 9 | + |
| 10 | + def insert(self, word: str) -> None: |
| 11 | + currentNode = self.root |
| 12 | + for char in word: |
| 13 | + if char not in currentNode.children: |
| 14 | + currentNode.children[char] = TrieNode() |
| 15 | + currentNode = currentNode.children[char] |
| 16 | + currentNode.isEndOfWord = True |
| 17 | + |
| 18 | +# <-- ์ฌ๊ธฐ๊น์ง Trie ๊ตฌํ์ ์ํ TrieNode์ Trie ํด๋์ค |
| 19 | +# --> ์ฌ๊ธฐ๋ถํฐ Word Break ๋ฌธ์ ํธ๋ Solution ํด๋์ค |
| 20 | + |
| 21 | +class Solution: |
| 22 | + def wordBreak(self, s: str, wordDict: List[str]) -> bool: |
| 23 | + |
| 24 | + # 1. ํธ๋ผ์ด ๊ตฌ์ถ |
| 25 | + # wordDict ๋ชจ๋ ๋จ์ด -> ํธ๋ผ์ด ๋ฃ๊ธฐ |
| 26 | + trie = Trie() |
| 27 | + for word in wordDict: |
| 28 | + trie.insert(word) |
| 29 | + |
| 30 | + n = len(s) # ๋ฌธ์์ด s์ ๊ธธ์ด, ๋์ค์ ์ธ๋ฑ์ค ๋๊น์ง ๋๋ฌํ๋์ง ํ์ธํ๊ธฐ ์ํด ์ฌ์ฉํจ |
| 31 | + |
| 32 | + # <<<--- ๋ฉ๋ชจ์ด์ ์ด์
์บ์ ์ด๊ธฐํ ---<<< |
| 33 | + # key: start_index, value: s[start_index:] ๋ถํ ๊ฐ๋ฅ ์ฌ๋ถ (True/False) |
| 34 | + memo = {} |
| 35 | + |
| 36 | + # 2. ์ฌ๊ท ํจ์ ์ ์ |
| 37 | + # canBreak(start_index): s[strat_index:] ๋ถ๋ถ์ ๋ถํ ํ ์ ์๋์ง ํ์ธ |
| 38 | + def canBreak(start_index: int) -> bool: |
| 39 | + |
| 40 | + # <<<--- ์บ์ ํ์ธ ---<<< |
| 41 | + # ์ด start_index์ ๋ํ ๊ฒฐ๊ณผ๊ฐ ์ด๋ฏธ memo์ ์์ผ๋ฉด ๋ฐ๋ก ๋ฐํ |
| 42 | + if start_index in memo: |
| 43 | + return memo[start_index] |
| 44 | + |
| 45 | + # ๋ฒ ์ด์ค ์ผ์ด์ค |
| 46 | + # ์์ ์ธ๋ฑ์ค(start_index)๊ฐ ๋ฌธ์์ด ๋์ ๋๋ฌํ๋ค๋ฉด ์ฑ๊ณต |
| 47 | + if start_index == n: |
| 48 | + return True |
| 49 | + |
| 50 | + # ํ์ฌ start_index๋ถํฐ ์์ํ๋ ๊ฐ๋ฅํ ๋ชจ๋ ๋จ์ด๋ฅผ ํธ๋ผ์ด๋ฅผ ์ด์ฉํด ์ฐพ๊ณ |
| 51 | + # ๊ฐ ๋จ์ด์ ๋ํด ๋๋จธ์ง ๋ถ๋ถ์ด ๋ถํ ๊ฐ๋ฅํ์ง ์ฌ๊ท์ ์ผ๋ก ํ์ธ |
| 52 | + currentNode = trie.root |
| 53 | + for i in range(start_index, n): |
| 54 | + char = s[i] |
| 55 | + |
| 56 | + # ํ์ฌ ๋ฌธ์๊ฐ ํธ๋ผ์ด ๊ฒฝ๋ก์ ์๋ค๋ฉด ํด๋น ํธ๋ผ์ด ํ์์ ๋์ด์ ์งํํ์ง ์์ |
| 57 | + if char not in currentNode.children: |
| 58 | + break |
| 59 | + |
| 60 | + # ํธ๋ผ์ด์ ๋ค์ ๋
ธ๋๋ก ์ด๋ |
| 61 | + currentNode = currentNode.children[char] |
| 62 | + |
| 63 | + # ์ด๋ํ ๋
ธ๋๊ฐ ๋จ์ด์ ๋์ด๋ผ๋ฉด |
| 64 | + if currentNode.isEndOfWord: |
| 65 | + # ๋๋จธ์ง ๋ถ๋ถ s[i+1:]์ ๋ํด์๋ ๋ถํ ๊ฐ๋ฅํ์ง ์ฌ๊ท ํธ์ถ |
| 66 | + if canBreak(i + 1): |
| 67 | + # ๋๋จธ์ง ๋ถ๋ถ ๋ถํ ์ฑ๊ณต => ์ ์ฒด ๋ถํ ๊ฐ๋ฅ |
| 68 | + # <<<--- ์ฑ๊ณต ๊ฒฐ๊ณผ ์บ์์ ์ ์ฅ ---<<< |
| 69 | + memo[start_index] = True |
| 70 | + return True |
| 71 | + # start_index๋ถํฐ ์์ํ๋ ๋ชจ๋ ๊ฐ๋ฅํ ๋จ์ด ๋ถํ ์ ์๋ํ์ผ๋ |
| 72 | + # ์ฑ๊ณต์ ์ธ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ง ๋ชปํ๋ค๋ฉด |
| 73 | + # <<<--- ์คํจ ๊ฒฐ๊ณผ ์บ์์ ์ ์ฅ ---<<< |
| 74 | + memo[start_index] = False |
| 75 | + return False |
| 76 | + |
| 77 | + # 3. ์ฌ๊ท ํจ์ ํธ์ถ ์์ |
| 78 | + return canBreak(0) |
0 commit comments