O(n*|S|)
내가 트리는에 관한 다음과 같은 생각을 가지고있다, 복잡도 O (N)는 : 당신은 빈 트리는 시작합니다. 단어 하나 하나를 가져 와서 단어를 Trie에 추가하십시오.
- 무선은 이전에 추가 한 단어의 일부 접두어 : 당신이 단어를 추가 한 후 트리는에 (의이 단어 무선 부르 자), 고려해야 할 두 가지 경우가 있습니다. 단어 Wi를 추가하는 동안 Trie에 노드를 추가하지 않으면이 명령문은 true입니다. 이 경우 Wi는 접두어이며 우리 솔루션의 일부입니다.
- 앞에 추가 된 단어 중 일부는 Wi의 접두사입니다. 이전에 추가 한 단어의 끝을 나타내는 노드를 통과 한 경우 해당 문이 true입니다 (해당 단어 Wj를 보정하자). 이 경우 Wj는 Wi의 접두어이며 우리의 솔루션의 일부입니다. 자세한 내용은에서
(의사) :
for word in words
add word to trie
if size of trie did not change then // first case
add word to result
if ending nodes found while adding word // second case
add words defined by those nodes to result
return result
트리는 새로운 단어를 추가 : 새 단어를 추가하는 동안 당신이 어떤 노드를 통과하면
node = trie.root();
for letter in word
if node.hasChild(letter) == false then // if letter doesnt exist, add it
node.addChild(letter)
if letter is last_letter_of_word then // if last letter of word, store that info
node.setIsLastLetterOf(word)
node = node.getChild(letter) // move
, 당신은 또한 확인하실 수 있습니다 다른 단어의 마지막 글자를 나타냅니다. 내가 설명한 알고리즘의 복잡도는 O (N)입니다. 또 다른 중요한 점은 단어 Wi가 다른 단어 앞에 몇 번이나 붙는 지 알 수 있기 때문에 유용 할 수 있습니다. 위한
예 {AAB, AABA, AA는} 그린 노드 1 레드 노드는 대소 2 각 열 (트라이)로 감지 노드에있는 경우로서 검출 노드이다 한 단계이다. 처음에는 trie가 비어 있습니다. 검은 색 화살표는 해당 단계에서 우리가 방문한 (추가 된) 노드를 나타냅니다. 일부 단어의 마지막 문자를 나타내는 노드는 해당 단어가 괄호 안에 쓰여 있습니다. 1 단계에서
은
- 우리는 단어 AAB를 추가합니다.
- 2 단계에서 단어 aaba를 추가하고 사례 2 (단어 aab)를 인식하고 단어 aab를 결과에 추가합니다.
- 3 단계에서 단어 aa를 추가하고 사례 1을 인식 한 다음 단어 aa를 결과에 추가합니다.
결국 우리는 결과 = {aab, aa}가 맞습니다.
솔루션을 정렬해도 시간이 많이 걸리지 않을 것입니다. 당신은 { "a", "aa", "aaa"}가 있다고 가정 해 봅시다 - O (nlog (n))에있는 것들을 정렬 할 수 있지만 "a"가 "aa"의 접두사인지, a "는"aaa "의 접두사이고"aa "는"aaa "의 접두사입니다 - O (n^2) – Archeg
@Michael O (N)에서 문제를 해결할 수있는 알고리즘을 제안했지만 결코 댓글을 달았습니다. 내 해결책이 정확한지 찾았습니까? 그렇다면 올바른 답으로 표시해주세요. 그렇다면 그대의 의견을 듣고 싶습니다. – Martinsos