znajdowanie najmniejszych k elementów w tablicy w O (k)

12

To interesujące pytanie znalazłem w Internecie. Biorąc pod uwagę tablicę zawierającą n liczb (bez informacji o nich), powinniśmy wstępnie przetworzyć tablicę w czasie liniowym, abyśmy mogli zwrócić k najmniejszych elementów w czasie O (k), gdy otrzymamy liczbę 1 <= k <= n

Dyskutowałem o tym problemie z przyjaciółmi, ale nikt nie mógł znaleźć rozwiązania; każda pomoc będzie mile widziana!

krótkie uwagi: - kolejność k najmniejszych elementów nie jest ważna - elementy w tablicy są liczbą, mogą być liczbami całkowitymi i mogą nie być (więc brak sortowania w radix) - liczba k nie jest znana na etapie wstępnego przetwarzania. przetwarzanie wstępne to czas O (n). funkcja (znajdź k najmniejszych elementów) w czasie O (k).

Idan
źródło
4
Co powiesz na korzystanie z min-sterty?
Shir
1
Spójrz na obliczenia k-skyband i top-k. Artykuł cs.sfu.ca/~jpei/publications/subsky_tkde07.pdf ma niezły przegląd powiązanej literatury.
András Salamon
1
Shir-ja zbadałem pomysł na min-stos. jednak w celu wydrukowania k najmniejszych liczb na stercie min jest czas O (klogn), a nie O (k) zgodnie z wymaganiami
Idan
4
@idannik: Jak myślisz, dlaczego potrzeba aby znaleźć k najmniejszych elementów na min-stercie? Ω(klogn)k
Kristoffer Arnsfelt Hansen
8
Nie sądzę, żeby to był poziom badań. Wygląda jak zadanie. Gdzie to znalazłeś?
Kaveh

Odpowiedzi:

24

Przetwórz wstępnie tablicę wartości w czasie O ( n ) :nO(n)

  • in
  • podczas gdy i>2
    • Obliczyć średnią o A [ 1 .. I ] w czasie O ( I )mA[1..i]O(i)
    • Partycja [ 1 .. I ] w A [ 1 .. I / 2 - 1 ] m i [ i / 2 + 1 .. I ] m w tym samym czasie.A[1..i]A[1..i/21]mA[i/2+1..i]m
    • ii/2

Całkowity czas precomputation jest w O(1+2+4+...+n)O(n)

Odpowiedz na zapytanie o najmniejszych elementów w A w czasie O ( k ) :kAO(k)

  • llog2k
  • wybierz th element x z A [ 2 l . .2 l + 1 ] w czasie O ( 2 l ) O ( k )(k2l)xA[2l..2l+1]O(2l)O(k)
  • przegroda przez x w tym samym czasieA[2l..2l+1]x

zawiera k najmniejszych elementów.A[1..k]k

Bibliografia:

  • W 1999 roku Dor i Zwick podali algorytm obliczający medianę elementów w czasie w ramach porównań 2.942 n + o ( n ) , co daje algorytm do wyboru k- tego elementu spośród n nieuporządkowanych elementów w mniej niż 6 n porównaniach.n2.942n+o(n)kn6n
Jeremy
źródło
1
Wydaje mi się, że zewnętrzna pętla powinna być „dla i w ”. Czy twój algorytm różni się od algorytmu zawartego w odpowiedzi Yuval Filmus? {2lgn,,4,2,1}
Radu GRIGore
2
To jest uogólnienie mojego algorytmu na dowolny . Zawiera również niektóre szczegóły implementacji, które (celowo) zostały pominięte w mojej odpowiedzi. n
Yuval Filmus
3
@YuvalFilmus Czy w swoim komentarzu chcesz zasugerować, że moja odpowiedź jest nieetycznie zbliżona do twojej? Jest to rozwiązanie, które przyszło mi do głowy, kiedy przejrzałem pytanie. Widziałem, że opublikowałeś podobny, ale okazało się, że jest niejasny, więc napisałem własny (w przeciwieństwie do robienia poważnych zmian). Ostatecznie liczy się jakość odpowiedzi w systemach, a nie to, kto je napisał: odznaki i reputacja to tylko zachęty, a nie same w sobie cele.
Jeremy
4
n
2
Och :( W takim razie przepraszam za to. (Chociaż nadal uważałbym, że udzielenie kompletnych odpowiedzi jest priorytetem w stosunku do podejrzeń o przydzielenie zadania)
Jeremy
14

n=2m2m1,2m2,2m3,,1kt2t1k2t2t2k2tkO(2t)=O(k)

Θ(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
źródło
1
O(1)kO(n)
4
lognnlogn
3
@ AndrásSalamon: Jeśli przeczytasz odpowiedź udzieloną przez Jeremy'ego (która wygląda mi prawie tak samo jak ta), zobaczysz, że najpierw przetwarzasz całą tablicę, potem pierwszą połowę i tak dalej.
Radu GRIGore
3
n+n/2+n/4++1<2n
5
Nawiasem mówiąc, ten algorytm pojawia się jako podprogram w mojej odpowiedzi na wcześniejsze pytanie: cstheory.stackexchange.com/questions/17378/…
David Eppstein
2

O(n)O(k)k

Frederickson, Greg N. , Optymalny algorytm do selekcji w hałdzie min. , Inf. Comput. 104, nr 2, 197–214 (1993). ZBL0818.68065 ..

hqztrue
źródło
1
kO(k)
@ a3nm To rzeczywiście nie jest prosty algorytm, ale zaktualizowałem referencję.
hqztrue
kkO(k)k
kx<xO(k)
kk/2k
0

kk

jbapple
źródło
1
k
2
Widzę. Mój błąd.
jbapple