Verarbeiten Sie ein Array zum Zählen eines Elements in einem Slice vor (Reduktion auf RMQ?)


11

Bei einem Array natürlicher Zahlen k , wobei k eine Konstante ist, möchte ich in O ( 1 ) -Anfragen der Form antworten : "Wie oft erscheint m im Array zwischen den Indizes i und j "?ein1,,einnkkÖ(1)michj

Das Array sollte in linearer Zeit vorverarbeitet werden. Insbesondere würde ich gerne wissen, ob es eine Reduzierung auf Range Minimum Query gibt.


Dies entspricht RMQ für den Fall, dass und Sie die Anzahl der Einsen innerhalb eines Intervalls abfragen möchten. So können wir nutzen es . Ich konnte meine eigene Frage wegen der SE-Grenzen nicht beantworten.k=1


Sie können die Elementunterscheidbarkeit auf Ihr Problem reduzieren (in linearer Zeit). Vielleicht ist es angebracht, über ein Modell zu sprechen?
Aryabhata

@Aryabhata Was genau ist das Problem der Elementunterscheidbarkeit? Jetzt lese ich dies: en.wikipedia.org/wiki/Range_Queries
andy

Dies ist viel einfacher als RMQ. Hinweis: Da k eine Konstante ist, kann die Vorverarbeitung Zeit proportional zu kn verbringen und zählt immer noch als lineare Zeit.
Tsuyoshi Ito

@Aryabhata: Die Reduktion, von der ich denke, dass Sie sprechen, funktioniert nicht, weil k eine Konstante in diesem Problem ist.
Tsuyoshi Ito

Nur für den Fall, dass das Array zu Beginn angegeben und danach nicht aktualisiert wird, ist RMQ ein Overkill, wie ich in meinem früheren Kommentar vorgeschlagen habe.
Tsuyoshi Ito

Antworten:


4

Da konstant ist, können wir die Anzahl jedes Elements im Bereich 0 .. m für 0 m < n in 0 .. n in O ( n k ) = O ( n ) Zeit und Raum speichern . Die primäre Beobachtung ist, dass Sie ein zweidimensionales Array in O ( n k ) -Zeit erstellen und dann Bereiche abfragen können, indem Sie die Differenz der i , j- Indizes in konstanter Zeit ermitteln.k0 ..m0m<n0 ..nÖ(nk)=Ö(n)count[pos][elem] = occurences of 'elem' in the indices 0..posÖ(nk)ich,j

Vorverarbeitung

initialise count[pos][elem] to 0 for all elem, pos
for pos=0 to n
  for num=0 to k
      count[pos][num] = (0 if pos==0 else count[pos-1][num])
  count[pos][arr[pos]] ++

Abfrage

(nimmt an, dass i, j beide inklusive Grenzen sind)

if i == 0
  return count[j][m]
else
  return count[j][m] - count[i-1][m]

kcountÖ(Logn)Ö(Logn)

Entschuldigung für alle Probleme mit dieser Antwort, es ist meine erste.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.