Qual é a maneira mais rápida de encontrar o K-menor valor em uma lista não classificada, sem classificar?

8

Meu algoritmo inicial:

  1. Compare o elemento 0 com qualquer outro elemento, acompanhando quantos elementos são menores que ele.
  2. Repita para cada elemento até encontrar um elemento maior que exatamente (k-1).

Suponho que isso levaria no pior caso. É possível obter um tempo de execução mais rápido sem classificar a lista?O(n2)

PORQUE
fonte
Você pode criar uma segunda lista e classificá-la? Ou seja, você pode criar uma lista dos k menores valores?
jmoreno

Respostas:

10

Use o algoritmo de seleção para tempo linear https://en.m.wikipedia.org/wiki/Selection_algorithm

Eugene
fonte
2
Em particular, Median of Medians, de Blum et al., 1973, resolve o problema de seleção no pior dos casos, no tempo linear. Provavelmente o algoritmo mais elegante que eu já vi.
quick
6
Embora isso responda à pergunta, é recomendável fazer uma descrição própria, não apenas um link.
Mal
4

Infelizmente, não posso apenas comentar, mas tenho que publicá-lo como resposta.

De qualquer forma, você pode tentar usar um min-heap em sua matriz não classificada, conseguir uma complexidade de tempo de O (n + k * logn).

Luca Giorgi
fonte
3
Infelizmente, não posso apenas comentar, mas tenho que publicá-lo como resposta.- o que foi uma coisa boa, pois respostas como a sua postagem não pertencem aos comentários. Os comentários são para melhorar as perguntas, não para respostas curtas ou similares.
Wrzlprmft
1
Ah, acho que a minha não é uma resposta completa para ser honesto, não dei detalhes específicos sobre por que ou como o uso de um heap mínimo poderia reduzir a complexidade do tempo, por isso senti que ele pertencia. mais em um comentário do que em uma resposta
Luca Giorgi
Isso depende de kse min-heap ou max-heap deve ser usado.
Mal
3

O algoritmo Quickselect pode fazer isso com O (n) complexidade média, é um dos algoritmos de seleção mais usados ​​de acordo com a Wikipedia .

É derivado do QuickSort e, como tal, sofre de uma complexidade de pior caso de O (n²) se você usar um pivô incorreto (um problema que pode ser evitado na prática).

O algoritmo em poucas palavras: após a rotação como no QuickSort, desça apenas para o lado inferior ou superior da matriz - dependendo de qual deles possui o elemento que você procura.

Nestor Demeure
fonte
2

Crie um heap máximo de tamanhok. O invariante é que o heap sempre contém ok menores elementos observados até agora.

  1. Insira o primeiro k elementos da lista na pilha
  2. Para cada elemento restante Eu na lista:
    • deixei M ser o elemento máximo na pilha
    • E se Eu<Me exclua M e insira Eu na pilha

No final, o heap conterá o k menores elementos da lista.

Procurar o elemento máximo tem custo constante. O custo de inserção e exclusão éO(k). A complexidade do tempo desse método éO(n.registrok)

Behrouz Babaki
fonte
1
Pilha máxima ou pilha mínima, depende de k> n / 2.
Mal
@ Evil Você deseja verificar se i é menor que qualquer um dos elementos no heap. Então, você quer saber se é menor que o maior deles. Procurando o elemento máximo é O (1) no heap máximo, mas não no heap mínimo.
Behrouz Babaki
1
Verdade. Imagine que k = 1 ou k = n, você usaria a mesma pilha nos dois casos? Talvez seja possível usar o min-heap de alguma forma quando é mais rápido? (Eu sei que é, você tem +1 de mim, apenas um nitpick, não se preocupe).
Mal
1
@ Evil Você está certo. Eu descartei seu comentário às pressas. Quando k> n / 2, pode-se usar um método semelhante para armazenar os (nk) maiores elementos em um min-heap. Os elementos removidos da pilha são o que queremos.
Behrouz Babaki