it-swarm.com.de

AMAZON Interview-Frage

In Anbetracht eines N-Arrays der Größe K ist jedes dieser K-Elemente in den N-Arrays sortiert, jedes dieser N * K-Elemente ist eindeutig. Wählen Sie aus jedem der N Arrays ein einzelnes Element aus der ausgewählten Teilmenge der N Elemente aus. Subtrahieren Sie das Minimum und Maximum Element. Nun, diese Differenz sollte so gering wie möglich sein Minimum. Hoffe das Problem ist klar :) :)

Probe:

N=3, K=3

N=1 : 6, 16, 67
N=2 : 11,17,68
N=3 : 10, 15, 100

wenn hier 16, 17, 15 gewählt werden, erhalten wir die minimale Differenz als 17-15 = 2.

19

Ich kann an O (N * K * N) denken (editiert nach korrekt hervorgehoben von zivo, jetzt keine gute Lösung :().
1. Nehmen Sie den N-Zeiger, der anfangs auf jedes der N-Arrays auf das Anfangselement zeigt.

6, 16, 67
^ 
11,17,68
^
10, 15, 100
^ 

2. Ermitteln Sie das höchste und das niedrigste Element unter dem aktuellen Zeiger O(k) (6 und 11) und ermitteln Sie die Differenz zwischen ihnen (5).
3. Erhöhen Sie den Zeiger, der auf das unterste Element zeigt, um 1 in diesem Array.

 6, 16, 67
    ^ 
 11,17,68
 ^
 10, 15, 100 (difference:5)
 ^ 

4. Wiederholen Sie Schritt 2 und 3 und speichern Sie die minimale Differenz. 

 6, 16, 67
    ^ 
 11,17,68
 ^
 10,15,100 (difference:5)
    ^ 


 6, 16, 67
    ^ 
 11,17,68
    ^
 10,15,100 (difference:2)
    ^ 

Oben wird die erforderliche Lösung sein.  

 6, 16, 67
    ^ 
 11,17,68
    ^
 10,15,100 (difference:84)
       ^ 

 6, 16, 67
        ^ 
 11,17,68
    ^
 10,15,100 (difference:83)
       ^ 

Und so weiter......

BEARBEITEN:

Seine Komplexität kann durch Verwendung eines Haufens (wie von Uri vorgeschlagen) reduziert werden. Ich dachte darüber nach, stieß jedoch auf ein Problem: Jedes Mal, wenn ein Element aus dem Heap extrahiert wird, muss seine Array-Nummer ermittelt werden, um den entsprechenden Zeiger für dieses Array zu erhöhen. Eine effiziente Methode zum Auffinden der Array-Nummer kann die Komplexität definitiv auf O (K * N log (K * N)) reduzieren. Eine naive Methode ist die Verwendung einer solchen Datenstruktur

Struct
{
    int element;
    int arraynumer;
}

und rekonstruieren die Ausgangsdaten wie

 6|0,16|0,67|0

 11|1,17|1,68|1

 10|2,15|2,100|2

Behalten Sie zunächst das aktuelle Maximum für die erste Spalte bei und fügen Sie die spitzen Elemente in den Heap ein. Jedes Mal, wenn ein Element extrahiert wird, kann seine Array-Nummer herausgefunden werden, der Zeiger in diesem Array wird inkrementiert, das neu angezeigte Element kann mit dem aktuellen Maximum verglichen werden und der Max-Zeiger kann entsprechend angepasst werden.

9
Terminal

Hier ist ein Algorithmus, um dieses Problem in zwei Schritten zu lösen:

Der erste Schritt besteht darin, alle Arrays in einem sortierten Array zusammenzuführen, das folgendermaßen aussehen würde:

combined_val [] - enthält alle Zahlen 
combined_ind [] - enthält den Index, zu welchem ​​Array diese Nummer ursprünglich gehörte

dieser Schritt kann leicht in O (K * N * log (N)) ausgeführt werden, aber ich denke, Sie können auch noch etwas besseres tun (vielleicht nicht, Sie können Varianten der Zusammenführungs-Sortierung suchen, da sie dem Schritt ähnlich sind).

Nun zweiter Schritt:

es ist einfacher, einfach Code einzugeben, anstatt ihn zu erklären. Hier ist der Pseduocode:


int count[N] = { 0 }
int head = 0;
int diffcnt = 0;
// mindiff is initialized to overall maximum value - overall minimum value
int mindiff = combined_val[N * K - 1] - combined_val[0];
for (int i = 0; i < N * K; i++) 
{
  count[combined_ind[i]]++;

  if (count[combined_ind[i]] == 1) {
    // diffcnt counts how many arrays have at least one element between
    // indexes of "head" and "i". Once diffcnt reaches N it will stay N and
    // not increase anymore
    diffcnt++;
  } else {
    while (count[combined_ind[head]] > 1) {
      // We try to move head index as forward as possible while keeping diffcnt constant.
      // i.e. if count[combined_ind[head]] is 1, then if we would move head forward
      // diffcnt would decrease, that is something we dont want to do.
      count[combined_ind[head]]--;
      head++;
    }
  }

  if (diffcnt == N) {
    // i.e. we got at least one element from all arrays
    if (combined_val[i] - combined_val[head] < mindiff) {
      mindiff = combined_val[i] - combined_val[head];
      // if you want to save actual numbers too, you can save this (i.e. i and head
      // and then extract data from that)
    }
  }
}

das Ergebnis ist in mindiff.

Die Laufzeit des zweiten Schrittes beträgt O (N * K). Dies liegt daran, dass der "Kopf" -Index sich nur um das N * K-fache bewegt. also macht die innere Schleife dies nicht quadratisch, sie ist immer noch linear.

Die Gesamtlaufzeit des Algorithmus ist also O (N * K * log (N)). Dies ist jedoch auf den Zusammenführungsschritt zurückzuführen. Wenn Sie einen besseren Zusammenführungsschritt ausführen können, können Sie ihn wahrscheinlich auf O (N * K) bringen.

3
zviadm

Dieses Problem ist für Manager

Sie haben 3 Entwickler (N1), 3 Tester (N2) und 3 DBAs (N3) Wählen Sie das weniger divergente Team aus, das ein Projekt erfolgreich ausführen kann.

int[n] result;// where result[i] keeps the element from bucket N_i

int[n] latest;//where latest[i] keeps the latest element visited from bucket N_i

Iterate elements in (N_1 + N_2 + N_3) in sorted order
{
    Keep track of latest element visited from each bucket N_i by updating 'latest' array;

    if boundary(latest) < boundary(result)
    {
       result = latest;
    }
}

int boundary(int[] array)
{
   return Max(array) - Min(array);
}
3
random

Korrektheitsnachweis für die akzeptierte Antwort (Lösung von Terminal)

Angenommen, der Algorithmus findet eine Reihe A = <A [1], A [2], ..., A [N]>, die nicht die optimale Lösung (R) ist.

Betrachten Sie den Index j in R, so dass Element R [j] das erste Element unter R ist, das der Algorithmus untersucht und durch das nächste Element in seiner Zeile ersetzt. 

Sei A 'die Kandidatenlösung in dieser Phase (vor dem Austausch). Da R [j] = A '[j] der Minimalwert von A' ist, ist es auch das Minimum von R. Betrachten wir nun den Maximalwert von R, R [m]. Wenn A '[m] <R [m], dann kann R verbessert werden, indem R [m] durch A' [m] ersetzt wird, was der Tatsache widerspricht, dass R optimal ist. Daher ist A '[m] = R [m]. Mit anderen Worten, R und A 'haben das gleiche Maximum und Minimum, daher sind sie gleichwertig. Damit ist der Beweis abgeschlossen: Wenn R eine optimale Lösung ist, wird der Algorithmus garantiert eine Lösung finden, die so gut wie R ist.

1
Eyal Schneider

Ich habe O (K * N * log (K)), mit typischer Ausführung viel weniger. Derzeit kann ich nichts besseres denken. Ich erkläre zuerst die leichter zu beschreibende (etwas längere Ausführung):

  1. Für jedes Element f im ersten Array (Schleife durch K-Elemente)
  2. Für jedes Array beginnend mit dem zweiten Array (Schleife durch N-1-Arrays)
  3. Führen Sie eine binäre Suche im Array durch und suchen Sie das Element, das am nächsten an f liegt. Dies ist dein Element (Log (K))

Dieser Algorithmus kann optimiert werden, wenn Sie für jedes Array einen neuen Floor-Index hinzufügen. Bei der Perforierung der binären Suche suchen Sie zwischen 'Floor' bis 'K-1'. Der Floor-Index ist anfangs 0, und nach dem ersten Element durchsuchen Sie die gesamten Arrays. Wenn Sie ein Element gefunden haben, das am nächsten an "f" liegt, aktualisieren Sie den Standindex mit dem Index dieses Elements. Der schlimmste Fall ist derselbe (Floor wird möglicherweise nicht aktualisiert, wenn das maximale Element des ersten Arrays kleiner als jedes andere Minimum ist), der durchschnittliche Fall wird jedoch verbessert.

1
Uri

für jedes Element im 1. Array

    choose the element in 2nd array that is closest to the element in 1st array
    current_array = 2;
    do
    {
        choose the element in current_array+1 that is closest to the element in current_array
        current_array++;
    } while(current_array < n);

komplexität: O (k ^ 2 * n)

0
user2120127

Hier ist meine Logik zur Lösung dieses Problems, wobei zu berücksichtigen ist, dass wir aus jedem der N-Arrays ein Element auswählen müssen (um das kleinste Minimum zu berechnen).

// if we take the above values as an example!
// then the idea would be to sort all three arrays while keeping another
// array to keep the reference to their sets (1 or 2 or 3, could be 
// extended to n sets)      
1   3   2   3   1   2   1   2   3    // this is the array that holds the set index
6   10  11  15  16  17  67  68  100  // this is the sorted combined array.
           |           |   
    5            2          33       // this is the computed least minimum,
                                     // the rule is to make sure the indexes of the values 
                                     // we are comparing are different (to make sure we are 
// comparing elements from different sets), then for example
// the first element of that example is index:1|value:6 we hold 
// that value 6 (that is the value we will be using to compute the least minimum, 
// then we go to the Edge of the comparison which would be the second different index, 
// we skip index:3|value:10 (we remove it from the array) we compare index:2|value:11 
// to index:1|value:6 we obtain 5 which would go to a variable named leastMinimum = 5, 
// now we remove the indexes and values we already used,
// and redo the same steps.

Schritt 1 :

1   3   2   3   1   2   1   2   3
6   10  11  15  16  17  67  68  100
           |   
5            
leastMinumum = 5

Schritt 2:

3   1   2   1   2   3
15  16  17  67  68  100
           |   
 2          
leastMinimum = min(2, leastMinumum) // which is equal 2

Schritt 3:

1   2   3
67  68  100

    33
leastMinimum = min(33, leastMinumum) // which is equal to old leastMinumum which is 2

Nun: Wir nehmen an, dass wir Elemente aus demselben Array haben, die sehr nahe beieinander liegen (k = 2, dies bedeutet, dass wir nur 3 Sets mit zwei Werten haben):

// After sorting the n arrays we will have the below indexes array and values array
1   1   2   3   2   3
6   7   8   12  15  16
*       *   *

* we skip second index of 1|7 and we take the least minimum of 1|6 and 3|12 (index:2|value:8 will be removed as it is not at the edges, we pick the minimum and maximum of the unique index subset of n elements)
1   3         
6   12
 =6
* second step we remove the values we already used, so the array become like below:

1   2   3
7   15  16
*   *   * 
7 - 16
= 9

Hinweis: Ein anderer Ansatz, der mehr Speicher benötigt, würde darin bestehen, N Unterarrays zu erstellen, aus denen wir das Maximum - Minumum vergleichen würden

Aus dem unten sortierten Werte-Array und dem entsprechenden Index-Array extrahieren wir drei weitere Sub-Arrays:

1   3   2   3   1   2   1   2   3
6   10  11  15  16  17  67  68  100

Erstes Array:

1   3   2 
6   10  11

11-6 = 5

Zweites Array:

3   1   2
15  15  17

17-15 = 2

Drittes Array:

1   2   3
67  68  100

100 - 67 = 33

0
Mehdi Karamosly