ps:problems:programmers:17685
[3차] 자동완성
ps | |
---|---|
링크 | programmers.co.kr/… |
출처 | 프로그래머스 |
문제 번호 | 17685 |
문제명 | [3차] 자동완성 |
레벨 | Level 4 |
분류 |
트라이 |
시간복잡도 | O(L) |
인풋사이즈 | L<=1,000,000 |
사용한 언어 | Python |
해결날짜 | 2021/01/04 |
풀이
- 친절하게도 문제에 해설링크가 걸려있다. 해설은 좀 짧막하게 써있지만, 트라이 (Trie)를 쓰는 방법과 소팅을 쓰는 방법이 있다는 힌트만 있으면 사실 해법은 쉽게 나온다.
- 문제에서 요구하는 것은, 각각의 단어에 대해서, 다른 단어와 공유되지 않는 가장 짧은 접두사의 길이를 구하는 것.
- 공식 해설의 두 방법중 정해는 트라이이다. 트라이를 구성할때에 각 노드에, 차일드의 갯수를 저장하도록 구현하면, O(L)시간에 트라이를 생성하면서 각 노드마다 차일드의 갯수도 같이 구할 수 있다, 이제 각 단어의 모든 접두사를 순회하며 차일드가 한개밖에 없는 접두사중 가장 짧은 것의 길이를 구하는 것 역시 O(L)에 해결 가능.
- Trie v2.0으로 업데이트하면서, 트라이를 생성할때에 차일드의 갯수를 저장하지는 않게 되었다. 하지만 트라이 생성 후에 다시 차일드의 갯수들을 구하는 것도 O(L)이라 복잡도에 차이는 없다
- 소팅을 하는 방법은, 소팅을 하고 나서는 인접한 단어들과만 비교하기 때문에, O(mn) ≈ O(L)시간에 비교가 가능하지만, 소팅에 O(mnlogn) ≈ O(Llogn)이 걸리므로 트라이보다는 시간 복잡도에서는 불리하다. (m은 각 단어의 평균 길이).
- 하지만 트라이 (Trie)에서 언급했듯, 파이썬에서는 이 방법이 더 빠르게 동작할 것이다. (해보지는 않음)
코드
"""Solution code for "Programmers 17685. [3차] 자동완성".
- Problem link: https://programmers.co.kr/learn/courses/30/lessons/17685
- Solution link: http://www.teferi.net/ps/problems/programmers/17685
"""
from teflib import string
def solution(words):
trie = string.Trie(words)
answer = 0
for word in words:
for i, node in enumerate(trie.prefixes(word)):
if trie.word_count(node) == 0 and trie.get_child_count(node) == 1:
answer += (i + 1)
break
else:
answer += len(word)
return answer
- Dependency: teflib.string.Trie
ps/problems/programmers/17685.txt · 마지막으로 수정됨: 2021/01/21 05:22 저자 teferi
토론