localizando os menores elementos k na matriz em O (k)

12

Esta é uma pergunta interessante que encontrei na web. Dado um array contendo n números (sem informações sobre eles), devemos pré-processar o array em tempo linear, para que possamos retornar os k menores elementos em O (k), quando recebermos um número 1 <= k <= n

Estive discutindo esse problema com alguns amigos, mas ninguém conseguiu encontrar uma solução; Qualquer ajuda seria apreciada!

notas rápidas: -a ordem dos k menores elementos não é importante -os elementos da matriz são número, podem ser números inteiros e podem não ser (portanto, nenhuma classificação de raiz) -o número k não é conhecido no estágio de pré-processamento. o pré-processamento é O (n) time. a função (encontre k elementos menores) no tempo O (k).

Idan
fonte
4
Que tal usar um min-heap?
21413 Shir
1
Veja o k-skyband e o cálculo dos top-k. O artigo cs.sfu.ca/~jpei/publications/subsky_tkde07.pdf apresenta uma boa revisão da literatura relacionada.
András Salamon
1
Shir-eu examinei a idéia de min-heap. no entanto, a fim de imprimir os k menores números em min pilha está em O (klogn) tempo e não O (k) como necessário
Idan
4
@idannik: Por que você acha que é preciso tempo para encontrar o k menores elementos em um min-heap? Ω(klogn)k
Kristoffer Arnsfelt Hansen
8
Eu não acho que isso seja nível de pesquisa. Parece uma tarefa. Onde você achou isso?
Kaveh

Respostas:

24

Pré-processe a matriz de valores no tempo O ( n ) :nO(n)

  • in
  • enquanto i>2
    • Calcule a mediana de A [ 1 .. i ] no tempo O ( i )mA[1..i]O(i)
    • partição em Um [ 1 .. i / 2 - 1 ] m e A [ i / 2 + 1 .. i ] m no mesmo tempo.A[1..i]A[1..i/21]mA[i/2+1..i]m
    • ii/2

O tempo total é precomputation dentro O(1+2+4+...+n)O(n)

Responda a uma consulta dos menores elementos em A no tempo O ( k ) :kAO(k)

  • llog2k
  • selecione o th elemento x de A [ 2 l . .2 l + 1 ] no tempo O ( 2 l ) O ( k )(k2l)xA[2l..2l+1]O(2l)O(k)
  • partição por x ao mesmo tempoA[2l..2l+1]x

contém os k menores elementos.A[1..k]k

Referências:

  • Em 1999, Dor e Zwick forneceram um algoritmo para calcular a mediana de elementos no tempo dentro de 2,942 n + o ( n ) comparações, o que produz um algoritmo para selecionar o k- ésimo elemento de n elementos não-ordenados em menos de 6 n comparações.n2.942n+o(n)kn6n
Jeremy
fonte
1
Eu acho que o loop externo deveria ser 'for i in '. Seu algoritmo é diferente do da resposta de Yuval Filmus? {2lgn,,4,2,1}
Radu Grigore
2
Esta é uma generalização do meu algoritmo para arbitrário . Também detalha alguns detalhes de implementação que foram (deliberadamente) deixados de fora da minha resposta. n
Yuval Filmus
3
@YuvalFilmus Deseja sugerir pelo seu comentário que minha resposta é antiética perto da sua? Esta é a solução que me veio à mente quando revi a pergunta. Vi que você postou um similar, mas não achou claro, então escrevi o meu (em vez de fazer uma edição maior sua). O que importa em última análise é a qualidade das respostas nos sistemas, não exatamente quem as escreveu: os crachás e a reputação são apenas incentivos, não objetivos em si mesmos.
Jeremy
4
@ Jeremy Nem um pouco; Só que as duas soluções são as mesmas (mas a sua funciona para arbitrário ), e que eu não especifiquei os detalhes no caso de ser uma questão de dever de casa. n
Yuval Filmus
2
Oh :( Desculpe por isso então (Althought eu ainda acho que dar respostas completas a ser uma prioridade sobre suspeitas de atribuição).
Jeremy
14

Suponha por simplicidade que n=2m . Use o algoritmo de seleção de tempo linear para encontrar os elementos nas posições ; isso leva tempo linear. Dado k , encontre t tal que 2 t - 1k 2 t ; note que 2 t2 k . Filtrar todos os elementos da classificação no máximo 2 t2m1,2m2,2m3,,1kt2t1k2t2t2k2te agora use o algoritmo de seleção de tempo linear para encontrar o elemento na posição no tempo O ( 2 t ) = O ( k ) .kO(2t)=O(k)

Esclarecimento: Pode parecer que o pré-processamento leva tempo , e que é realmente o caso, se você não tiver cuidado. Aqui está como fazer o pré-processamento em tempo linear:Θ(nlogn)

while n > 0:
  find the (lower) median m of A[0..n-1]
  partition A in-place so that A[n/2-1] = m
  n = n/2

n+n/2+n/4++1<2nAkA[0..n/2k1]n/2k

Yuval Filmus
fonte
1
O(1)kO(n)
4
lognnlogn
3
@ AndrásSalamon: Se você ler a resposta dada por Jeremy (que me parece quase a mesma), verá que primeiro processa toda a matriz, depois a primeira metade e assim por diante.
Radu GRIGore
3
n+n/2+n/4++1<2n
5
Aliás este algoritmo aparece como uma sub-rotina na minha resposta a uma pergunta anterior: cstheory.stackexchange.com/questions/17378/...
David Eppstein
2

O(n)O(k)k

Frederickson, Greg N. , Um algoritmo ideal para seleção em um min-heap , Inf. Comput. 104, No. 2, 197-214 (1993). ZBL0818.68065 ..

hqztrue
fonte
1
kO(k)
@ a3nm Na verdade, não é um algoritmo simples, mas atualizei a referência.
Hqztrue 19/05/19
Desculpe, pelo que sei, a referência que você adicionou apenas fala sobre a seleção do kkO(k)k
@ a3nm sim, a referência fornece apenas o valor de kx<xO(k)
kk/2k
0

kk

jbapple
fonte
1
k
2
Entendo. Meu erro.
Jbapple