๐Ÿ’ซ ETC/Leetcode

Week 3-2. [Trie] 208. Implement Trie (Prefix Tree) (Python3)

ming412 2023. 9. 12. 00:20

๋ฌธ์ œ ํ•ด๊ฒฐ ๊ณผ์ •

โœ๏ธ ๋ฌธ์ œ ์š”์•ฝ

https://leetcode.com/problems/implement-trie-prefix-tree/?envType=study-plan-v2&envId=top-interview-150 

 

Implement Trie (Prefix Tree) - LeetCode

Can you solve this real interview question? Implement Trie (Prefix Tree) - A trie [https://en.wikipedia.org/wiki/Trie] (pronounced as "try") or prefix tree is a tree data structure used to efficiently store and retrieve keys in a dataset of strings. There

leetcode.com

โžก๏ธ insert, search, startsWith ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๋Š” Trie ์ž๋ฃŒ ๊ตฌ์กฐ๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•˜๋ผ.

 

๐Ÿ”Ž ์–ด๋–ค ์‹์œผ๋กœ ์ ‘๊ทผํ–ˆ๋Š”๊ฐ€?

insert()

๋ฃจํŠธ ๋…ธ๋“œ๋ถ€ํ„ฐ ํ•˜๋‚˜์”ฉ ์ž์‹ ๋…ธ๋“œ๋ฅผ ์ˆœํšŒํ•˜๋ฉด์„œ word์˜ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์—†์„ ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

 

search()

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ฃจํŠธ ๋…ธ๋“œ๋ถ€ํ„ฐ ์ž์‹ ๋…ธ๋“œ๋ฅผ ์ˆœํšŒํ•˜๋Š”๋ฐ, ์ด๋ฒˆ์—๋Š” word์˜ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์—†์„ ๋•Œ ๋ฐ”๋กœ False๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

startsWith()

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ฃจํŠธ ๋…ธ๋“œ๋ถ€ํ„ฐ ์ž์‹ ๋…ธ๋“œ๋ฅผ ์ˆœํšŒํ•˜๋Š”๋ฐ, ์ด๋ฒˆ์—๋Š” prefix์˜ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์—†์„ ๋•Œ ๋ฐ”๋กœ False๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

๐ŸŽฏ ํ’€์ด

์žฌ๊ท€๋ฅผ ์ด์šฉํ•œ ํ’€์ด์ด๋‹ค.

class Node:
    def __init__(self):
        self.children = dict()
        self.isEndOfWord = False

class Trie:
    def __init__(self):
        self.root = Node()

    def insert(self, word: str) -> None:
        self._insert(self.root, word)

    def _insert(self, node: Node, word: str) -> None:
        if len(word) == 0:
            node.isEndOfWord = True
            return
        c = word[0]
        child = node.children.get(c)
        if child is None:
            node.children[c] = Node() # ์ƒˆ๋กœ์šด ๋…ธ๋“œ ์ถ”๊ฐ€
            child = node.children.get(c)
        self._insert(child, word[1:])

    def search(self, word: str) -> bool:
        return self._search(self.root, word)

    def _search(self, node: Node, word: str) -> bool:
        if len(word) == 0:
            return node.isEndOfWord
        c = word[0]
        child = node.children.get(c)
        if child is None: 
            return False
        return self._search(child, word[1:])

    def startsWith(self, prefix: str) -> bool:
        node = self.root
        for x in prefix:
            child = node.children.get(x)
            if child == None: return False
            node = child
        return True


        


# Your Trie object will be instantiated and called as such:
# obj = Trie()
# obj.insert(word)
# param_2 = obj.search(word)
# param_3 = obj.startsWith(prefix)

์•„๋ž˜์ฒ˜๋Ÿผ ์‚ฝ์ž…ํ•  ๋•Œ ์žฌ๊ท€๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

# ๋ฐ˜๋ณต๋ฌธ ์‚ฌ์šฉ
def insert(self, word: str) -> None:
    node = self.root
    for c in word:
        if not c in node.children:
            node.children[c] = Node()
        node = node.children[c]
    node.isEndOfWord = True

์œ„ ์ฝ”๋“œ์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” ์ค‘์œ„ ์ˆœํšŒ๋ฅผ ํ†ตํ•ด ์ด์ง„ ํŠธ๋ฆฌ์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ํ•œ ๋ฒˆ์”ฉ ๋ฐฉ๋ฌธํ•˜๋ฏ€๋กœ O(n)์ด๋‹ค. 

๋ฌธ์ œ์—์„œ ์ž…๋ ฅ์˜ ์ตœ๋Œ€๋Š” 10^4์ด๋ฏ€๋กœ ๊ฐ๋‹นํ•  ์ˆ˜ ์žˆ๋Š” ์ •๋„์ด๋‹ค.

 

๋‹ค๋ฅธ ์‚ฌ๋žŒ์˜ ์ฝ”๋“œ๋ฅผ ํƒ๊ตฌํ•ด๋ณด๊ธฐ

์žฌ๊ท€๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„ ๋”์šฑ ์‰ฝ๊ณ  ์ดํ•ดํ•˜๊ธฐ ์ข‹๋‹ค.

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” ์ด์ง„ ํŠธ๋ฆฌ์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ํ•œ ๋ฒˆ์”ฉ ๋ฐฉ๋ฌธํ•˜๋ฏ€๋กœ O(n)์ด๋‹ค. 

 

class Node:
    def __init__(self):
        self.children = dict()
        self.isEndOfWord = False

class Trie:
    def __init__(self):
        self.root = Node()

    def insert(self, word: str) -> None:
        node = self.root
        for c in word:
            if c not in node.children:
                node.children[c] = Node()
            node = node.children[c]
        node.isEndOfWord = True

    def search(self, word: str) -> bool:
        node = self.root
        for c in word:
            if c in node.children:
                node = node.children[c]
            else: return False
        return node.isEndOfWord

    def startsWith(self, prefix: str) -> bool:
        node = self.root
        for c in prefix:
            if c in node.children:
                node = node.children[c]
            else: return False
        return True


        


# Your Trie object will be instantiated and called as such:
# obj = Trie()
# obj.insert(word)
# param_2 = obj.search(word)
# param_3 = obj.startsWith(prefix)