[Programmers] P17685 자동완성
[Programmers] P17685 자동완성
Question
Language: Python
해당 문제는 Trie algorithm을 응요해서 해결하는 문제이다.
- 해당 노드의 자식에 대응되는 key 값이 없는 경우 [value, children] 값을 만들어준다.
-
해당 문자열을 끝까지 도달할 때 까지 trie 노드를 순회하면서 trie에 데이터를 넣는다.
- trie의 root에서 부터 내려오면서 해당 문자열에 대한 prefix 개수를 확인한다.
- 3.1: 순회 과정에서 value가 1이라는 의미는 해당 경로 1개라는 의미로, 특정 문자열만을 뜻하게 되므로 순회를 종료한다.
- 3.2: 모든 prefix을 봤는데도, value가 1이 없다는 것은 다른 문자열에 해당 문자열이 포함되어 있는 경우가 존재한다는 의미이므로, 해당 문자열의 길이 만큼이 prefix가 되는 것이다.
Solution 1
def solution(words):
answer = 0
words.sort()
trie={}
for word in words:
cur_trie=trie
for char in word:
#1
cur_trie.setdefault(char,[0,{}])
cur_trie[char][0]+=1
#2
cur_trie=cur_trie[char][1]
for word in words:
cur_trie=trie
for i in range(len(word)):
#3-1
if cur_trie[word[i]][0]==1:
break
cur_trie=cur_trie[word[i]][1]
#3-2
answer+=(i+1)
return answer
아니면 아래와 같이 모든 단어에 대해 사전순으로 비교해서 인접한 문자열에 대한 비교를 수행하여 더 긴 prefix 길이를 구한다.
Solution 2
def solution(words):
answer = 0
words.sort()
for idx, word in enumerate(words):
res=1
if idx > 0:
for i,char in enumerate(word):
res=max(res,i+1)
if len(words[idx-1])==i or words[idx-1][i] != char:
break
if idx+1 < len(words):
for i,char in enumerate(word):
res=max(res,i+1)
if len(words[idx+1])==i or words[idx+1][i] != char:
break
answer+=res
return answer
Trie Algorithm
class Node:
def __init__(self,key,data=None):
self.key=key
self.data=data
self.children=dict()
class Trie:
def __init__(self):
self.head=Node(None)
def insert(self,string):
current_node=self.head
for char in string:
current_node.children.setdefault(char,Node(char))
current_node=current_node.children[char]
current_node.data=string
def search(self,string):
current_node=self.head
for char in string:
if char in current_node.children:
current_node=current_node.children[char]
else:
return False
if current_node.data:
return True
else:
return False
def starts_with(self,prefix):
current_node=self.head
words=[]
for p in prefix:
if p in current_node.children:
current_node=current_node.children[p]
else:
return None
current_node=[current_node]
nodes=[]
while True:
for node in current_node:
if node.data:
words.append(node.data)
nodes.extend(list(node.children.values()))
if len(nodes) !=0:
current_node=nodes
nodes=[]
else:
break
return words
댓글남기기