πŸ’»μ½”λ”©ν…ŒμŠ€νŠΈ λ¬Έμ œν’€μ΄22

μ§€λ―Όμ„œΒ·2023λ…„ 3μ›” 16일
0

coding test

λͺ©λ‘ 보기
21/30

Chapter11. 자주 λ“±μž₯ν•˜λŠ” 자료 ꡬ쑰

[문제51] 가사 검색 - Level4

μΉœκ΅¬λ“€λ‘œλΆ€ν„° 천재 ν”„λ‘œκ·Έλž˜λ¨Έλ‘œ λΆˆλ¦¬λŠ” 'ν”„λ‘œλ„'λŠ” μŒμ•…μ„ ν•˜λŠ” μΉœκ΅¬λ‘œλΆ€ν„° μžμ‹ μ΄ μ’‹μ•„ν•˜λŠ” λ…Έλž˜ 가사에 μ‚¬μš©λœ 단어듀 쀑에 νŠΉμ • ν‚€μ›Œλ“œκ°€ λͺ‡ 개 ν¬ν•¨λ˜μ–΄ μžˆλŠ”μ§€ κΆκΈˆν•˜λ‹ˆ ν”„λ‘œκ·Έλž¨μœΌλ‘œ κ°œλ°œν•΄λ‹¬λΌλŠ” μ œμ•ˆμ„ λ°›μ•˜μŠ΅λ‹ˆλ‹€.

κ·Έ μ œμ•ˆ 사항 쀑, ν‚€μ›Œλ“œλŠ” μ™€μΌλ“œμΉ΄λ“œ 문자 쀑 ν•˜λ‚˜μΈ '?'κ°€ ν¬ν•¨λœ νŒ¨ν„΄ ν˜•νƒœμ˜ λ¬Έμžμ—΄μ„ λœ»ν•©λ‹ˆλ‹€. μ™€μΌλ“œ 문자인'?'λŠ” κΈ€μž ν•˜λ‚˜λ₯Ό μ˜λ―Έν•˜λ©°, μ–΄λ–€ λ¬Έμžμ—λ„ λ§€μΉ˜λœλ‹€κ³  κ°€μ •ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ "fro??"λŠ” "frodo", "front", "frost" 등에 λ§€μΉ˜λ˜μ§€λ§Œ "frame", "frozen"μ—λŠ” λ§€μΉ˜λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

가사에 μ‚¬μš©λœ λͺ¨λ“  단어듀이 λ‹΄κΈ΄ λ°°μ—΄ words와 찾고자 ν•˜λŠ” ν‚€μ›Œλ“œκ°€ λ‹΄κΈ΄ λ°°μ—΄ queriesκ°€ μ£Όμ–΄μ§ˆ λ•Œ ν‚€μ›Œλ“œλ³„λ‘œ 맀치된 단어가 λͺ‡ κ°œμΈμ§€ μˆœμ„œλŒ€λ‘œ 배열에 λ‹΄μ•„ λ°˜ν™˜ν•˜λ„λ‘ solution ν•¨μˆ˜λ₯Ό μ™„μ„±ν•΄μ£Όμ„Έμš”.

[가사 단어 μ œν•œμ‚¬ν•­]

  • words의 길이(가사 λ‹¨μ–΄μ˜ 개수)λŠ” 2 이상 100,000 μ΄ν•˜μž…λ‹ˆλ‹€.
  • 각 가사 λ‹¨μ–΄μ˜ κΈΈμ΄λŠ” 1 이상 10,000 μ΄ν•˜λ‘œ 빈 λ¬Έμžμ—΄μΈ κ²½μš°λŠ” μ—†μŠ΅λ‹ˆλ‹€.
  • 전체 가사 단어 길이의 합은 2 이상 1,000,000 μ΄ν•˜μž…λ‹ˆλ‹€.
  • 가사에 동일 단어가 μ—¬λŸ¬ 번 λ‚˜μ˜¬ 경우 쀑볡을 μ œκ±°ν•˜κ³  wordsμ—λŠ” ν•˜λ‚˜λ‘œλ§Œ μ œκ³΅λ©λ‹ˆλ‹€.
  • 각 가사 λ‹¨μ–΄λŠ” 였직 μ•ŒνŒŒλ²³ μ†Œλ¬Έμžλ‘œλ§Œ κ΅¬μ„±λ˜μ–΄ 있으며, 특수 λ¬Έμžλ‚˜ μˆ«μžλŠ” ν¬ν•¨ν•˜μ§€ μ•ŠλŠ” κ²ƒμœΌλ‘œ κ°€μ •ν•©λ‹ˆλ‹€.

[검색 ν‚€μ›Œλ“œ μ œν•œμ‚¬ν•­]

  • queries의 길이(검색 ν‚€μ›Œλ“œ 개수)λŠ” 2 이상 100,000 μ΄ν•˜μž…λ‹ˆλ‹€.
  • 각 검색 ν‚€μ›Œλ“œμ˜ κΈΈμ΄λŠ” 1 이상 10,000 μ΄ν•˜λ‘œ 빈 λ¬Έμžμ—΄μΈ κ²½μš°λŠ” μ—†μŠ΅λ‹ˆλ‹€.
  • 전체 검색 ν‚€μ›Œλ“œ 길이의 합은 2 이상 1,000,000 μ΄ν•˜μž…λ‹ˆλ‹€.
  • 검색 ν‚€μ›Œλ“œλŠ” 쀑볡될 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
  • 각 검색 ν‚€μ›Œλ“œλŠ” 였직 μ•ŒνŒŒλ²³ μ†Œλ¬Έμžμ™€ μ™€μΌλ“œμΉ΄λ“œ 문자인 '?'둜만 κ΅¬μ„±λ˜μ–΄ 있으며, 특수 λ¬Έμžλ‚˜ μˆ«μžλŠ” ν¬ν•¨ν•˜μ§€ μ•ŠλŠ” κ²ƒμœΌλ‘œ κ°€μ •ν•©λ‹ˆλ‹€.
  • 검색 ν‚€μ›Œλ“œλŠ” μ™€μΌλ“œμΉ΄λ“œ 문자인 '?'κ°€ ν•˜λ‚˜ 이상 포함돼 있으며, '?'λŠ” 각 검색 ν‚€μ›Œλ“œμ˜ 접두사 μ•„λ‹ˆλ©΄ 접미사 쀑 ν•˜λ‚˜λ‘œλ§Œ μ£Όμ–΄μ§‘λ‹ˆλ‹€.
    • 예λ₯Ό λ“€μ–΄ "??odo", "fro??", "?????"λŠ” κ°€λŠ₯ν•œ ν‚€μ›Œλ“œμž…λ‹ˆλ‹€.
    • λ°˜λ©΄μ— "frodo"('?'κ°€ μ—†μŒ), "fr?do"('?'κ°€ 쀑간에 있음"), "?ro??"('?'κ°€ μ–‘μͺ½μ— 있음)λŠ” λΆˆκ°€λŠ₯ν•œ ν‚€μ›Œλ“œμž…λ‹ˆλ‹€.

[μ½”λ“œμž‘μ„±]

1. 트라이 자료 ꡬ쑰 생성
1-1. λ…Έλ“œ μ •μ˜

class Node(object):
	def __init__(self, key):
    	self.key = key
        self.count = 0
        self.children = {}

1-2. 트라이 자료 ꡬ쑰 μ •μ˜

//1) μ„ μ–Έ ν›„ μ΄ˆκΈ°ν™”
class Trie(object):
	def __init__(self):
    	self.head = Node(self)
        
//2) μ‚½μž…
def insert(self, string):
	current = self.head
    
    for char in string:
    	current.count += 1
        if char not in current.children:
        current.children[char] = Node(char)
        current = current.children(char)
        
//3) 탐색
def starts_with(self, prefix):
	current = self.head
    result = 0
    
    for char in prefix:
    	if char == '?': break
        if char in current.children: current = current.children[char]
        else: return 0
        
    return current.count

2. 단어λ₯Ό λ°›μ•„ νŠΈλΌμ΄μ— 데이터 μ±„μš°κΈ°
2-1. 초기 μ„€μ •

def solution(words, queries):
	answer = []
    tries = {}
    reverse_tries = {}

2-2. 데이터 μ±„μš°κΈ°

for word in words:
	size = len(word)
    if size not in tries:
    	tries[size] = Trie()
        reverse_tries[size] = True()
        
    tries[size].insert(word)
    reverse_tries[size].insert(word[::-1])

3. 쿼리에 맞좰 탐색 진행

for query in queries:
	if len(query) in tries:
    	if query[0] != '?':
        	trie = tries[len(query)]
            answer.append(trie.starts_with(query))
        else:
        	trie = reverse_tries[len(query)]
            answer.append(trie.starts_with(query[::-1]))
    else: answer.append(0)

[μ „μ²΄μ½”λ“œ]

class Node(object):
	def __init__(self, key):
    	self.key = key
        self.count = 0
        self.children = {}
        
class Trie(object):
	def __init__(self):
    	self.head = Node(self)
        
def insert(self, string):
	current = self.head
    
    for char in string:
    	current.count += 1
        if char not in current.children:
            current.children[char] = Node(char)
        current = current.children(char)
        
def starts_with(self, prefix):
	current = self.head
    result = 0
    
    for char in prefix:
    	if char == '?': break
        if char in current.children: current = current.children[char]
        else: return 0
        
    return current.count
    
def solution(words, queries):
	answer = []
    tries = {}
    reverse_tries = {}
    
    for word in words:
        size = len(word)
        if size not in tries:
            tries[size] = Trie()
            reverse_tries[size] = True()

        tries[size].insert(word)
        reverse_tries[size].insert(word[::-1])
        
    for query in queries:
        if len(query) in tries:
            if query[0] != '?':
                trie = tries[len(query)]
                answer.append(trie.starts_with(query))
            else:
                trie = reverse_tries[len(query)]
                answer.append(trie.starts_with(query[::-1]))
        else: answer.append(0)
        
    return answer
profile
πŸ’» + πŸŽ₯

0개의 λŒ“κΈ€